Frage

Ich bin ein noob in Shell-Scripting. Ich möchte eine Nachricht drucken und meinen Skript zu beenden, wenn ein Befehl fehlschlägt. Ich habe versucht:

my_command && (echo 'my_command failed; exit)

, aber es funktioniert nicht. Es hält die Ausführung von Anweisungen im Anschluss an diese Zeile im Skript. Ich bin mit Ubuntu und bash.

War es hilfreich?

Lösung

Versuchen Sie:

my_command || { echo 'my_command failed' ; exit 1; }

Vier ändert:

  • Ändern && zu ||
  • Verwenden Sie { } anstelle von ( )
  • Vorstellen
  • ; nach exit und
  • Leerzeichen nach { und vor }

Da Sie die Nachricht und Ausfahrt nur drucken möchten, wenn der Befehl fehlschlägt (Ausfahrten mit Nicht-Null-Wert) benötigen Sie einen || kein &&.

cmd1 && cmd2

wird cmd2 laufen, wenn cmd1 erfolgreich ist (Exit-Wert 0). Wo, wie

cmd1 || cmd2

wird cmd2 laufen, wenn cmd1 fehlschlägt (Exit-Wert nicht Null).

( ) Verwendung macht den Befehl in ihnen in einem Unter Shell ausgeführt und ruft eine exit von dort führt Sie die Unterschale zu verlassen und nicht Ihre ursprüngliche Shell, damit die Ausführung fortgesetzt in Ihrer ursprünglichen Shell.

Um diese Verwendung { } zu überwinden

Die beiden letzten Änderungen von bash erforderlich sind.

Andere Tipps

Die anderen Antworten haben die direkte Frage gut gedeckt, aber Sie können auch Sie sich mit dem set -e interessieren. Damit jeder Befehl, der (außerhalb von spezifischen Kontexten wie if Tests) nicht bewirkt, dass das Skript abzubrechen. Für bestimmte Skripte, dann ist es sehr nützlich.

Wenn Sie dieses Verhalten für alle Befehle in Ihrem Skript möchten, fügen Sie einfach

  set -e 
  set -o pipefail

am Anfang des Skripts. Dieses Paar Optionen sagt dem Bash-Interpreter zu verlassen, wenn ein Befehl kehrt mit einem Nicht-Null-Exit-Code.

Dies erlaubt Ihnen nicht, eine Exit-Nachricht zu drucken, though.

Beachten Sie auch, jeder Exit-Status des Befehls wird in dem Shell-Variable $ ?, gespeichert, die Sie sofort nach dem Ausführen des Befehls überprüfen. Ein Nicht-Null-Status zeigt Fehler an:

my_command
if [ $? -eq 0 ]
then
    echo "it worked"
else
    echo "it failed"
fi

Ich habe folgendes Idiom gehackt:

echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi

echo "Done."

Precede jeden Befehl mit einem informativen Echo, und folgen Sie jedem Befehl mit der gleichen
 if [ $? -ne 0 ];... Linie. (Natürlich können Sie diese Fehlermeldung bearbeiten, wenn Sie wollen.)

Sofern my_command kanonisch ausgebildet ist, dh 0 zurück, wenn erfolgreich ist, dann ist && genau das Gegenteil von dem, was Sie wollen. Sie wollen ||.

Beachten Sie auch, dass ( nicht richtig in bash mir scheint, aber ich kann nicht versuchen, von wo ich bin. Sagen Sie mir.

my_command || {
    echo 'my_command failed' ;
    exit 1; 
}

Sie können auch verwenden, wenn Sie Ausgang Fehlerstatus erhalten wollen, und haben eine lesbare Datei mit einem Befehl pro Zeile:

my_command1 || exit $?
my_command2 || exit $?

Dies wird jedoch keine zusätzliche Fehlermeldung drucken. Aber in einigen Fällen wird der Fehler ohnehin durch den gescheiterten Befehl gedruckt werden.

Die trap Schale builtin ermöglicht Signale und andere nützliche Bedingungen, einschließlich der gescheiterten Befehlsausführung (d.h., ein Nicht-Null Rückgabestatus) zu kontrollieren. Also, wenn Sie wollen nicht explizit Test Rückgabestatus jeden einzelnen Befehls kann man sagen trap "your shell code" ERR und der Shell-Code werden jedesmal, wenn ein Befehl gibt einen Nicht-Null-Status ausgeführt werden. Zum Beispiel:

trap "echo script failed; exit 1" ERR

Beachten Sie, dass wie bei anderen Fällen gescheiterte Befehle zu kontrollieren, Pipelines spezielle Behandlung benötigen; die oben wird nicht fangen false | true.

Folgende Funktionen sind nur Echos Fehler, wenn ein Befehl fehlschlägt:

silently () {
    label="${1}"
    command="${2}"
    error=$(eval "${command}" 2>&1 >"/dev/null")

    if [ ${?} -ne 0 ]; then
        echo "${label}: ${error}" >&2
        exit 1
    fi
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top