2009-07-02 1 views
22

In einer Art try/catch Form möchte ich eine bash ausführen, die nicht stoppt, wenn ein Fehler auftritt.Führen Sie einen Shell-Befehl aus einem Shell-Skript ohne zu stoppen, wenn ein Fehler auftritt

Die spezifische bash ist:

#!/bin/sh 

invoke-rc.d tomcat stop 

rm -fr /var/webapps/ 
cp -R $WEBAPP /var/webapps/ 
invoke-rc.d tomcat start 

I "invoke-rc.d tomcat stoppen" exec will und auch wenn Tomcat nicht ausgeführt wird, weiterhin die anderen bash Befehle auszuführen.

+6

Ist das Standardverhalten dieser Bash nicht? Ich hätte schwören können, dass es war (Sie müssen explizite Maßnahmen ergreifen, um ein Skript zu beenden, wenn ein Befehl fehlschlägt ...) –

+0

Wenn Sie dieses Skript ausführen und Tomcat nicht ausgeführt wird, wird das Skript die Ausführung stoppen, da der erste Befehl einen Fehler zurückgibt. Ich möchte, dass das Skript fortgesetzt wird. – JorgeO

+0

@Alex: Es ist Standard, aber es gibt wahrscheinlich etwas, das die Standardeinstellung überschreibt. –

Antwort

28

Versuchen:

invoke-rc.d tomcat stop > /dev/null 2>&1 || true 

Ein wenig Hintergrund:

[email protected]: # true 
[email protected]: # echo $? 
0 
[email protected]: # false 
[email protected]: # echo $? 
1 

[email protected]: # which true 
/bin/true 
[email protected]: # which false 
/bin/false 

Die echte Lösung wird bei dem tomcat Init-Skript schauen, um zu sehen, wie es weiß, ob Kater :) auf diese Weise ausgeführt wird, Sie belästigen es nicht unnötig.

Siehe this post auf den anderen Vorschlag zu deaktivieren/set + e. Während es Ihr unmittelbares Problem lösen könnte, stellen Sie möglicherweise fest, dass Sie das kürzlich nicht definierte Verhalten in Ihrem eigenen Skript benötigen, besonders, da Sie Dateien kopieren.

Dies ist einer der Hauptgründe, warum True und False gemacht wurden, abgesehen davon, dass Makefiles sich in einer Vielzahl von Build-Umgebungen wie erwartet verhalten.

Auch set + e ist nicht vollständig portierbar, d. H. Einige Versionen von Solaris (und sogar Dash) .. aber ich bezweifle, dass dies ein Anliegen für Sie ist.

+0

Ich habe die Pfade deines Codes und des Root-Benutzers entfernt, weil jemand denkt, dass du su sein musst.Hoffe, dass es Ihnen nichts ausmacht;) –

+0

@victor hugo - Danke. Ich habe diesen Beitrag ein paar Mal bearbeitet und habe nicht bemerkt, dass ich die Wege im Takt verlassen habe. Ich muss heute ein bisschen hirntot sein. –

+0

Ich verstehe eigentlich nicht den Teil 2> & 1 || wahr. Ich verstehe>/dev/null bedeutet, dass der Fehler dorthin umgeleitet wird, aber ich verstehe weder die Syntax noch die Bedeutung des anderen Teils. Kannst du es vielleicht erklären? – Toskan

-3

Versuchen Sie, den Standardfehler in eine Datei umzuleiten ... etwas wie 2> myerror.

+0

Wenn etwas wie Befehl>/dev/null gesehen. Ist es so? Dadurch wird die Ausgabe des Befehls in eine Datei verschoben. Aber fängt auch der Fehler auf? – JorgeO

+0

Dies wird nicht von dem Fehler behoben, es verbirgt lediglich die Ursache. –

4

Verwenden Sie bash's set command, um das Verhalten "Exit-on-nonzero" vorübergehend zu deaktivieren.

set +e 
invoke-rc.d tomcat stop 
set -e 
+0

Sie sollten eine kleine Erklärung Ihres Skripts schreiben. Klicken Sie einfach auf "Bearbeiten". BTW Willkommen zu SO –

+0

Satz {args} ist nicht immer tragbar. Wenn Sie jedoch folgendes tun: set + e || { Code, um mit einer hirntoten Hülle fertig zu werden } Es ist gut für alles, was es wert ist in POSIX-Konformität. Universell ist es viel einfacher (und viel portabler), nur wahr/falsch zu verwenden. –

28

Deaktivieren Sie die "exit sofort" Option mit set +e, führen Sie Ihren Befehl, dann gegebenenfalls wieder aktivieren mit set -e:

set +e 
invoke-rc.d tomcat stop 
set -e # optional 

Siehe section 4.3.1 der Bash Handbuch für eine Erklärung des set builtin und all seine verschiedenen Möglichkeiten (von denen es viele gibt).

1

Wenn invoke-rc.d Tomcat stoppen ist die einzige Sache, die Sie vor dem Scheitern schützen möchten, vielleicht invoke-rc.d Tomcat Stop || true kann es tun? Das sollte niemals einen Nicht-Null-Exit-Status haben.