387 Stimmen

Beenden Sie das Shell-Skript basierend auf dem Prozess-Exit-Code

Ich habe ein Shell-Skript, das eine Reihe von Befehlen ausführt. Wie mache ich das Shell-Skript beenden, wenn einer der Befehle mit einem Nicht-Null-Exit-Code beendet?

0 Stimmen

Harter Weg: Testen Sie den Wert von $? nach jedem Befehl. Einfacher Weg: Geben Sie set -e oder #!/bin/bash -e oben in Ihr Bash-Skript ein.

21voto

http://cfaj.freeshell.org/shell/cus-faq-2.html#11

  1. Wie erhalte ich den Beendigungscode von cmd1 in cmd1|cmd2

    Zunächst sei darauf hingewiesen, dass der Beendigungscode von cmd1 auch dann nicht null sein kann und trotzdem kein Fehler bedeutet. Dies passiert zum Beispiel in

    cmd | head -1

    Man könnte einen Beendigungscode von 141 (oder 269 bei ksh93) für cmd1 beobachten, aber das liegt daran, dass cmd durch ein SIGPIPE-Signal unterbrochen wurde, als head -1 nach dem Lesen einer Zeile beendet wurde.

    Um den Beendigungscode der Elemente einer Pipeline zu erfahren cmd1 | cmd2 | cmd3

    a. mit Z-Shell (zsh):

    Die Beendigungscode werden im speziellen Array pipestatus bereitgestellt. Der Beendigungscode von cmd1 befindet sich in $pipestatus[1], der Beendigungscode von cmd3 in $pipestatus[3], sodass $? immer gleich ist wie $pipestatus[-1].

    b. mit Bash:

    Die Beendigungscode werden im speziellen Array PIPESTATUS bereitgestellt. Der Beendigungscode von cmd1 befindet sich in ${PIPESTATUS[0]}, der Beendigungscode von cmd3 in ${PIPESTATUS[2]}, sodass $? immer gleich ist wie ${PIPESTATUS: -1}.

    ...

    Weitere Details finden Sie unter _Z-Shell_.

0 Stimmen

Der erste Link ist defekt: "Wir können keine Verbindung zum Server unter cfaj.freeshell.org herstellen."

19voto

Für Bash:

# Dieser Befehl fängt Fehler oder Befehle mit Exit-Status ungleich Null
# indem die Funktion catch_errors() aufgerufen wird
trap catch_errors ERR;

#
# ... der Rest des Skripts kommt hier hin
#

function catch_errors() {
   # Mach etwas bei Fehlern
   #
   #
   echo "Skript abgebrochen wegen Fehlern";
   exit 0;
}

21 Stimmen

Möglicherweise sollte man nicht "exit 0" verwenden, da dies auf Erfolg hindeutet.

4 Stimmen

Exit_code=$?;echo "Skript abgebrochen, aufgrund von Fehlern";exit $exit_code

11voto

Martin W Punkte 1329

In Bash ist das einfach. Einfach mit && verknüpfen:

command1 && command2 && command3

Sie können auch die verschachtelte if-Konstruktion verwenden:

if command1
   then
       if command2
           then
               do_something
           else
               exit
       fi
   else
       exit
fi

0 Stimmen

+1 Das war die einfachste Lösung, nach der ich gesucht habe. Außerdem kannst du auch if (! command) schreiben, wenn du von command einen nichtnullen Fehlercode erwartest.

0 Stimmen

Dies ist für sequenzielle Befehle... Was ist, wenn ich möchte, dass alle drei gleichzeitig gestartet werden und alle getötet werden, wenn einer von ihnen fehlschlägt?

4voto

Yordan Georgiev Punkte 4516
#
#------------------------------------------------------------------------------
# Zweck: um einen Befehl auszuführen, die Befehlsausgabe protokollieren, bei einem Fehler abbrechen
# Verwendung:
# set -e; do_run_cmd_or_exit "$cmd" ; set +e
#------------------------------------------------------------------------------
do_run_cmd_or_exit(){
    cmd="$@" ;

    do_log "DEBUG führe Befehl aus oder beende: \"$cmd\""
    msg=$($cmd 2>&1)
    export exit_code=$?

    # Falls während der Ausführung ein Fehler auftritt, mit Fehler beenden
    error_msg="Fehler beim Ausführen des Befehls:
        \"$cmd\" mit der Ausgabe:
        \"$msg\" !!!"

    if [ $exit_code -ne 0 ] ; then
        do_log "FEHLER $msg"
        do_log "FATAL $msg"
        do_exit "$exit_code" "$error_msg"
    else
        # Falls keine Fehler aufgetreten sind, protokolliere einfach die Nachricht
        do_log "DEBUG : Befehlsausgabe : \"$msg\""
    fi

}

3 Stimmen

Es gibt selten einen Grund, $* zu verwenden; verwenden Sie stattdessen "$@", um Leerzeichen und Platzhalterzeichen beizubehalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X