Der Unterschied von
a || b || c gegenueber
a; a_ret=$?; b; b_ret=... ist allerdings, dass in der ersten Variante
b nicht mehr ausgefuehrt wird, sobald
a gescheitert ist.
Ein vielleicht sogar funktionierender Ansatz:
set -e und eine
trap auf
EXIT. Wie sich herausstellt, ja, es geht:
Code: Alles auswählen
#!/bin/sh
a() { echo a; true; }
b() { echo b; false; }
c() { echo c; true; }
theshowmustgoon() {
set +e;
trap '' EXIT;
false; # no problem
echo "I don't exit yet";
}
trap theshowmustgoon EXIT;
set -e;
a;
b;
c;
theshowmustgoon;
echo 'real exit here';
Zuerst wird
a,
b und
c definiert.
b wird irgendwie fehlerhaft sein und einen
!=0-Rueckgabewert haben. Dieser wird wegen des
set -e unten aber das Skript beenden. Allerdings wird in der Zeile drueber eine Fall (
trap) fuer genau dieses Ende aufgestellt. D.h. wenn das Skript eigentlich beendet werden sollte, wird trotzdem noch
theshowmustgoon aufgerufen. Dies wurde oben definiert und schaltet errexit und die
trap wieder ab. In dieser Funktion muss auch saemtlicher Code sein, der eigentlich direkt nach
a; b; c liegen wuerde.
real exit here wird nicht gedruckt:
Sofern
b; aber nicht explodiert (weil man den Aufruf unten auskommentiert hat, wird die Funktion einfach ausgefuehrt), ohne zu beenden:
Das Problem bei der Aktion ist allerdings, dass im ersten Fall
c trotzdem nicht ausgefuehrt wird, man mit der Konstruktion also nur eine ein bisschen flexiblere Variante von
a || b || c erreicht.
Gruss Cae