Ich bin ein Neuling im Shell-Scripting. Ich möchte eine Nachricht drucken und mein Skript beenden, wenn ein Befehl fehlschlägt. Ich habe es versucht:
my_command && (echo 'my_command failed; exit)
aber es funktioniert nicht. Die Anweisungen, die dieser Zeile im Skript folgen, werden weiterhin ausgeführt. Ich benutze Ubuntu und Bash.
linux
bash
exit
exitstatus
user459246
quelle
quelle
Antworten:
Versuchen:
Vier Änderungen:
&&
zu||
{ }
anstelle von( )
;
Nachexit
und vorstellen{
und vor}
Da Sie die Nachricht drucken und nur beenden möchten, wenn der Befehl fehlschlägt (wird mit einem Wert ungleich Null beendet), benötigen Sie ein
||
nicht ein&&
.wird ausgeführt,
cmd2
wenn diescmd1
erfolgreich ist (Exit-Wert0
). Wohingegenwird ausgeführt,
cmd2
wenn eincmd1
Fehler auftritt (Exit-Wert ungleich Null).Wenn Sie verwenden,
( )
wird der darin enthaltene Befehl in einer Unter-Shell ausgeführt. Wennexit
Sie von dort aus a aufrufen , verlassen Sie die Unter-Shell und nicht Ihre ursprüngliche Shell. Daher wird die Ausführung in Ihrer ursprünglichen Shell fortgesetzt.Um diese Verwendung zu überwinden
{ }
Die letzten beiden Änderungen sind für bash erforderlich.
quelle
{ (>&2 echo 'my_command failed') ; exit 1; }
Die anderen Antworten haben die direkte Frage gut abgedeckt, aber Sie könnten auch daran interessiert sein, sie zu verwenden
set -e
. Bei jedem fehlgeschlagenen Befehl (außerhalb bestimmter Kontexte wieif
Tests) wird das Skript abgebrochen. Für bestimmte Skripte ist es sehr nützlich.quelle
set -e
gibt ein langes und arkanes Regelwerk darüber, wann es funktioniert und wann nicht. (Wenn jemand ausgeführt wirdif yourfunction; then ...
,set -e
wird er niemals im Innerenyourfunction
oder in einem von ihm aufgerufenen Objekt ausgelöst, da dieser Code als "aktiviert" betrachtet wird.) Lesen Sie den Übungsabschnitt von BashFAQ # 105 , in dem diese und andere Fallstricke erläutert werden (von denen einige nur für bestimmte Shell-Versionen gelten. Sie müssen also sicherstellen, dass Sie gegen jede Version testen, die zum Ausführen Ihres Skripts verwendet werden kann).Beachten Sie auch, dass der Exit-Status jedes Befehls in der Shell-Variablen $? Gespeichert ist, die Sie unmittelbar nach dem Ausführen des Befehls überprüfen können. Ein Status ungleich Null zeigt einen Fehler an:
quelle
echo "Just finished step A"
, dass jemand ein hinzugefügt hat , ohne zu wissen, dass dies dasecho
überschrieb$?
, was später überprüft werden sollte.Wenn Sie dieses Verhalten für alle Befehle in Ihrem Skript wünschen, fügen Sie einfach hinzu
am Anfang des Skripts. Dieses Optionspaar weist den Bash-Interpreter an, das Programm zu beenden, wenn ein Befehl mit einem Exit-Code ungleich Null zurückgegeben wird.
Auf diese Weise können Sie jedoch keine Beendigungsnachricht drucken.
quelle
trap
integrierten Befehl bash ausführen .set -o pipefail
möglicherweise nicht das gewünschte Verhalten vorliegt. Trotzdem danke für den Hinweis!set -e
ist überhaupt nicht zuverlässig, konsistent oder vorhersehbar! Um sich davon zu überzeugen, lesen Sie den Übungsabschnitt von BashFAQ # 105 oder die Tabelle, in der das Verhalten verschiedener Muscheln unter inulm.de/~mascheck/various/set-eIch habe die folgende Redewendung gehackt:
Stellen Sie jedem Befehl ein informatives Echo voran und folgen Sie jedem Befehl mit derselben
if [ $? -ne 0 ];...
Zeile. (Natürlich können Sie diese Fehlermeldung bearbeiten, wenn Sie möchten.)quelle
if ! javac *.java; then ...
- warum$?
überhaupt?Vorausgesetzt
my_command
ist kanonisch gestaltet, dh gibt 0 zurück, wenn dies erfolgreich ist, und&&
ist dann genau das Gegenteil von dem, was Sie wollen. Du willst||
.Beachten Sie auch, dass
(
mir das in Bash nicht richtig erscheint, aber ich kann nicht versuchen, wo ich bin. Sag mir.quelle
Sie können auch Folgendes verwenden, wenn Sie den Status des Beendigungsfehlers beibehalten und eine lesbare Datei mit einem Befehl pro Zeile haben möchten:
Dadurch wird jedoch keine zusätzliche Fehlermeldung ausgegeben. In einigen Fällen wird der Fehler jedoch trotzdem durch den fehlgeschlagenen Befehl gedruckt.
quelle
exit $?
; nurexit
verwendet$?
als seinen Standardwert.Die integrierte
trap
Shell ermöglicht das Abfangen von Signalen und anderen nützlichen Bedingungen, einschließlich fehlgeschlagener Befehlsausführung (dh eines Rückgabestatus ungleich Null). Wenn Sie also nicht den Rückgabestatus jedes einzelnen Befehls explizit testen möchten, können Sie sagen, dasstrap "your shell code" ERR
der Shell-Code jedes Mal ausgeführt wird, wenn ein Befehl einen Status ungleich Null zurückgibt. Beispielsweise:trap "echo script failed; exit 1" ERR
Beachten Sie, dass Pipelines wie in anderen Fällen, in denen fehlgeschlagene Befehle abgefangen werden, eine besondere Behandlung benötigen. das oben genannte wird nicht fangen
false | true
.quelle