automatische Rückgabe des `source`d-Skripts bei Befehlsfehler

automatische Rückgabe des `source`d-Skripts bei Befehlsfehler

Wie erreiche ich, dass ein sourceD-Skript automatisch zurückkehrt, wenn ein darin enthaltener Befehl fehlschlägt?

Angenommen, ich habe ein Skript, das bei einem Fehler automatisch beendet wird set -e, beispielsweise

#!/bin/bash
# foo.env
set -e        # auto-exit on any command failure
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

grepWenn ich den Befehl normal ausführe, wird er bei dem fehlgeschlagenen Befehl automatisch beendet :

box1% ./foo.env
hi
grep: 456: No such file or directory

Wenn ich das Skript jedoch sourceausführe, wird meine aktuelle Shell beendet und nicht nur das als Quelle verwendete Skript:

box1% ssh box2
box2% source ./foo.env
hi
grep: 456: No such file or directory
Connection to box2 closed.
box1%

Wenn ich das entferne set -e,

#!/bin/bash
# foo2.env
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

sourcedann wird das d-Skript weder automatisch beendet noch automatisch zurückgegeben :

box1% ssh box2
box2% source ./foo2.env
hi
grep: 456: No such file or directory
should not reach here
box2%

Der einzige Workaround, den ich bisher gefunden habe, besteht darin, returnjeder Codezeile im Skript einen Ausdruck hinzuzufügen, z. B.

box1% cat foo3.env
#!/bin/bash
# foo3.env - works, but is cumbersome
echo "hi" || return
grep 123 456 || return
echo "should not reach here" || return

box1% source foo3.env
hi
grep: 456: No such file or directory
box1%

Gibt es für sourceD-Skripte eine andere Möglichkeit, die der set -efür Nicht- sourceD-Skripte ähnelt?

Antwort1

Wenn Sie sourceein Skript verwenden, ist es so, als würden Sie die Datei Zeile für Zeile über die Tastatur schreiben. Das bedeutet, dass set -edie aktuelle Shell berücksichtigt wird und im Fehlerfall die aktuelle Shell beendet wird.

Das ist ein Workaround. Heute bin ich zu faul, also dachte ich, der Computer könnte ||returnfür mich schreiben oder besser noch die Datei Zeile für Zeile lesen und so ausführen:

#!/bin/bash
# this is the file MySource.sh
while IFS='' read -r line
do
   [[ $line == \#* ]] || $line || return
done < "$1"

Führen Sie es aus mit. MySource.sh FileToBeSourced.sh

Wenn deinZu Beziehende Datei.shDas Skript sollte mit einzeiligen Befehlen funktionieren.
Noch weit entfernt, um in einer Produktionsumgebung eingesetzt werden zu können.
Testen Sie es unddie Nutzung erfolgt auf eigene Gefahr.

Es überspringt Zeilen, die mit beginnen, #da diese den Fehler verursachen sollten # command not found.

verwandte Informationen