Wie führe ich mehrere Skripts innerhalb eines Skripts aus, selbst wenn ein Skript fehlschlägt?

2993
Dave

Ich habe ein einfaches Bash-Skript, das eine Reihe anderer Skripts ausführt.

#/bin/bash … ./update_artifact1.sh $ARTIFACT_VERSION ./update_artifact2.sh $ARTIFACT_VERSION ./update_artifact3.sh $ARTIFACT_VERSION 

Das Problem ist, wenn der erste Befehl (oder der zweite Befehl) mit einem Fehler stirbt, wird keiner der nachfolgenden Befehle ausgeführt. Gibt es eine Möglichkeit, alle drei Befehle auszuführen, den Exitstatus von jedem zu speichern und dann einen erfolgreichen Exitstatus zurückzugeben, wenn alle drei erfolgreich ausgeführt werden? Die Skripts müssen nicht gleichzeitig ausgeführt werden.

0
Was Sie zeigen, bedeutet nicht, dass das Hauptskript sterben sollte. Was steckt hinter "..."? glenn jackman vor 10 Jahren 2
Wenn der Befehl "./update_artifact1.sh $ ARTIFACT_VERSION" fehlschlägt, werden die beiden anderen Befehle ("./update_artifact2.sh $ ARTIFACT_VERSION" und "./update_artifact3.sh $ ARTIFACT_VERSION") nicht ausgeführt. Verstehst du? Dave vor 10 Jahren 0
ja, ich will. Aber wenn Sie `cd / unknown_dir versuchen; Echo ok`, der Echo-Befehl wurde ausgeführt, obwohl CD fehlgeschlagen ist. ** Warum ** schlagen der 2. und 3. Befehl in Ihrem Skript fehl? Hast du `set -e` eingeschaltet? Verlassen sich der 2. und 3. Befehl auf etwas, das der 1. bereitstellt? Gibt es eine Fehlerausgabe? Sie müssen weitere Informationen angeben. glenn jackman vor 10 Jahren 3

1 Antwort auf die Frage

0
Hastur

Sie können Ihr Skript auf diese Weise leicht modifizieren

#!/bin/bash … ./update_artifact1.sh $ARTIFACT_VERSION exit_state_1=$? ./update_artifact2.sh $ARTIFACT_VERSION exit_state_2=$? ./update_artifact3.sh $ARTIFACT_VERSION exit_state_3=$? exit_state_all=$[ $exit_state_1 && $exit_state_2 && $exit_state_3 ] exit $exit_state_all 

Hinweis:

  • Jeder Befehl gibt einen Beendigungscode zurück, der in bashgespeichert wird $?. Dies ist der 0Fall, wenn kein Fehler vorliegt, oder eine andere Nummer, wenn ein Fehler vorliegt.
    Nach jeder Zeile wird der Wert von $?aktualisiert. Sie müssen also in einer Variablen speichern (in diesem Fall haben wir exit_state_1... verwendet exit_state_n).
    Am Ende möchten Sie, dass Ihr Skript nur einen Fehlercode mit 0 zurückgibt, wenn alles in Ordnung ist und wir es mit verwirklichen $[ $a || $b || $c ].
    Beachten Sie, dass $[ 0|| 0 || 0 ]0 gleich ist, $[ $a || $b || $c ]wobei mindestens ein Ein $a,$b,$cnicht gleich 01 ist.
  • Es ist wichtig das ! in der ersten Zeile, wenn Sie schreiben müssen #!/bin/bash, um dem System mitzuteilen, dass es sich um ein Skript handelt, das in einer bashShell ausgeführt werden muss.
    Vielleicht finden Sie hier mehr über den Shebang .
  • Wie auch in einem Kommentar erwähnt set -e, wird das Skript beim ersten Fehler unterbrochen, ohne dass die andere Zeile verarbeitet wird, und es wird ein Fehlercode (derjenige des zuletzt ausgeführten Befehls) zurückgegeben, wenn Sie etwas vor diese Zeile einfügen.