Eine Meldung an den Nutzer übergeben, falls ein Kommando einen Exit-Status>0 hat

tuxlover

tuxlover

Der den Tux knuddelt
hallo allerseits,

ich habe über die letzten zwei wochen ein bisschen meine skills in sachen shell-programmierung verfeinert. offensichtlich aber nicht gut genug :( naja übung macht den meister.

also ich will folgendes machen. in einem shellscrpt sollen mehrere Kommandos ausgeführt werden, wenn eines der Kommandos fehlschlägt müsste es einen Exit-Status > 0 meistens 1 zurückgeben. dises wollte ich dann benutzen, um den Nutzer auf einen fehler aufmerksam zu machen.

hier den entsprechende Code wie ich mir das überlegt habe:

Code:
 Command1
EXIT_STATUS1=$?
.
.
.
Commandn
EXIT_STATUSn=$?

if [ $EXIT_STATUS1 && ...&& EXIT_STATUSn >0  ]
then
echo "ERROR"
exit ERROR
else
echo "!!!All fine!!!"

natürlich funktioniert das nicht er meckert zum einen in den Zeilen wo die EXIT_STATI abgefragt werden mit der Meldung bash:1 command not found und zum anderen in der zeile mit dem test. von wegen 0 kennt er nicht.

was mache ich falsch bzw. wie macht mans richtig?
 
Zuletzt bearbeitet:
Eine (von vielen) Möglichkeiten:

Code:
command1 &&
command2 &&
... &&
echo ok || echo error

Gruss, Xanti
 
ja irgendwie funktioinert das. aber kannst du mir erklären wieso das so funktioniert?

danke tuxlover
 
&& entspricht dem logischen Und, || dem Oder.
Die Shell ist bemüht, Konstrukte mit && und || zu einem Erfolg zu führen und zu merken, wann es unmöglich ist.

Die Anweisung cmd1 && cmd2 wird so interpretiert, dass der Rückgabewert von cmd1 (erfolgreich ausgeführt = true, Fehler = false) ausgewertet wird. Ist er false, weiß die Shell, dass die gesamte Anweisung unmöglich true annehmen kann und führt cmd2 nicht mehr aus. Also nur im Falle cmd1=true wird cmd2 ausgeführt.

cmd1 || cmd2 wird entsprechend ausgewertet, dass cmd2 nur ausgeführt wird, wenn cmd1=false ist.
 
Anderer Ansatz, den ich selber gerne nutze (kommt mir etwas flexibler vor als o.g. weil die Kdos nicht direkt hintereinander stehen müssen):

Code:
EXIT_STATUS=0
Command1 || EXIT_STATUS=$?
. 
# hier können auch andere Sachen stehen, die nicht getestet werden
.
Commandn || EXIT_STATUS=$?

if [ $EXIT_STATUS != 0  ] ; then
  echo "ERROR"
  exit ERROR
else
  echo "!!!All fine!!!"
fi
Der Exitstatus muß ja nur einmal festgehalten werden. So setzt jeder fehlgeschlagene Programmaufruf den Exitcode, jeder geglückte Aufruf läßt die Variable unverändert.
Ist die Variable am Schluß ungleich 0 (kann ja auch negative Exitcodes geben, oder nicht?), ist eines der Progs fehlgeschlagen.
Auch macht die Erweiterung weniger Probleme, da keine Variablen hinzugefügt werden müssen.

Gruß
XL
 
@schlaubi: wieso denn erschrecken. Aber vielleicht ist dann ein

Code:
echo "All fine :)"

besser.

@Xanti danke schön jetzt verstehe ich auch warum es funktioniert. das zweifleos die elegantere methode. :) danke

@x-lette kann es sein, dass bei deinem beispiel die Variable EXIT_STATUS jedesmal neu gesetzt wird?.
 
...
@x-lette kann es sein, dass bei deinem beispiel die Variable EXIT_STATUS jedesmal neu gesetzt wird?.

Die Variable wird nur gesetzt, wenn irgendwo ein Befehl fehlerhaft war. Wenn sie also zum Schluss nicht gesetzt ist, ist alles ok.
 
@x-lette kann es sein, dass bei deinem beispiel die Variable EXIT_STATUS jedesmal neu gesetzt wird?.
Es besteht aber dennoch ein gravierender Unterschied zu Xanties Lösung!

Bei Xantie wird die Befehlskette beendet, sobald ein Befehl fehlschlägt.
Im zweiten Fall wird erst zum Schluss ausgewertet, die weiteren Commands aber ausgeführt.

Wenn du z.B. ein
tar -czf file.tar.gz testdatei &&rm -f testdatei
hast, wird im zweiten Fall die Testdatei gelöscht, auch wenn das Tararchiv nicht erstellt werden konnte!
Die Meldung am Ende nutzt dann wenig.:devil:
Siehst du den kleinen aber bedeutenden Unterschied.? ;)

Nur mal so am Rande bemerkend
Gruß Wolfgang
 
Es besteht aber dennoch ein gravierender Unterschied zu Xanties Lösung!

Bei Xantie wird die Befehlskette beendet, sobald ein Befehl fehlschlägt.
Im zweiten Fall wird erst zum Schluss ausgewertet, die weiteren Commands aber ausgeführt.

Wenn du z.B. ein
tar -czf file.tar.gz testdatei &&rm -f testdatei
hast, wird im zweiten Fall die Testdatei gelöscht, auch wenn das Tararchiv nicht erstellt werden konnte!
Die Meldung am Ende nutzt dann wenig.:devil:
Siehst du den kleinen aber bedeutenden Unterschied.? ;)

Nur mal so am Rande bemerkend
Gruß Wolfgang
:D Gut bemerkt.
Da aber keine konkreten Anforderungen gegeben waren, lediglich diverse Kommandos ausgeführt werden sollten und am Schluss EIN Statuscode ausgegeben werden sollte, finde ich meine Lösung nach wie vor sauber und elegant. :)

Sollten aber Zusammenhänge irgendeiner Art zwischen den einzelnen Kommandos bestehen, müssen diese natürlich berücksichtigt werden.
Das sollte dann aber auch in der Fragestellung kenntlich gemacht sein.

Gruß
XL
 
das heißt jetzt für den zweiten fall. dass es eventuell unnötig lange laufzeiten gibt, wenn man z.b 100 befehle hintereinander ausführen will und der zweite berreits einen fehler verursacht.
 
das heißt jetzt für den zweiten fall. dass es eventuell unnötig lange laufzeiten gibt, wenn man z.b 100 befehle hintereinander ausführen will und der zweite berreits einen fehler verursacht.

Du kannst do selbst entscheiden, was passieren soll wenn ein Commando einen Fehler erzeugt.
Dafür gibt es z.B. exit
Schreib dir eine Errorfunktion, und benutze die im Fehlerfall als Ausstieg.

Gruß Wolfgang
PS Guter Programmierstil zeichnet sich auch dadurch aus, dass Fehler abgefangen werden!
 
Zurück
Oben