Ich weiß, dass set -e
das mein Freund ist, um bei einem Fehler zu beenden. Aber was tun, wenn das Skript bezogen wird, z. B. wenn eine Funktion über die Konsole ausgeführt wird? Ich möchte die Konsole nicht bei einem Fehler schließen, sondern nur das Skript stoppen und die Fehlermeldung anzeigen.
Muss ich die $ überprüfen? von jedem Befehl von Hand, um dies zu ermöglichen?
Hier ein Beispielskript myScript.sh
, um das Problem zu zeigen:
#!/bin/sh
set -e
copySomeStuff()
{
source="$1"
dest="$2"
cp -rt "$source" "$dest"
return 0
}
installStuff()
{
dest="$1"
copySomeStuff dir1 "$dest"
copySomeStuff dir2 "$dest"
copySomeStuff nonExistingDirectory "$dest"
}
Das Skript wird folgendermaßen verwendet:
$ source myScript.sh
$ installStuff
Dadurch wird nur die Konsole geschlossen. Der von angezeigte Fehler cp
geht verloren.
cp
Fehler beim Beenden und Beenden mit 1 Exit-Code.set -e
dieerrexit
Option in der Shell festgelegt. Beim Aufrufen der Funktioncp
schlägt die fehl und die Shell wird für mich beendet.#!
undset -e
auf die aufrufende Shell angewendet wird, gilt dies auch für alle nachfolgenden Befehle.()
wenn Shell-Funktionen aufgerufen werden.${dest}
und${source}
sind immer noch nicht zitiert und enthalten Benutzereingaben. Ich bin hier etwas wählerisch mit Ihnen, aber Sie müssen sie in Ihrem Skript auf Ihrem Computer zitieren, sonst funktionieren einfache Dinge wie das Kopieren von Dateien mit Leerzeichen in ihren Namen nicht. Es tut uns leid. Ich versuche nur, konstruktives Feedback zu geben.Antworten:
Ich würde empfehlen, ein Skript zu haben, das Sie als Sub-Shell ausführen und möglicherweise eine Datei zum Einlesen von Funktionsdefinitionen beziehen. Lassen Sie dieses Skript die
errexit
Shell-Option für sich selbst festlegen .Wenn Sie
source
über die Befehlszeile verwenden, ist "das Skript" effektiv Ihre interaktive Shell. Beenden bedeutet, die Shell-Sitzung zu beenden. Es gibt möglicherweise Möglichkeiten, dies zu umgehen, aber die beste Option, wenn Sieerrexit
eine Sitzung festlegen möchten, besteht darin, einfach Folgendes zu haben:Zusätzlicher Vorteil: Verschmutzt die interaktive Sitzung nicht mit Funktionen.
quelle
Wenn Sie dies als Quelle angeben, wird das ignoriert
#!
undset -e
auf die aufrufende Shell angewendet. Dies gilt auch für alle nachfolgenden Befehle.Sie könnten eine Sub-Shell erzwingen:
Auch zur Sicherheit:
Verwenden Sie nicht alle Caps-Variablennamen, da diese wahrscheinlich mit Umgebungsnamen kollidieren. (Wir hatten letzte Woche eine Frage, warum ein Skript nicht funktioniert hat, es hatte eine Variable PATH)
Verwenden Sie Anführungszeichen.
Immer Nutzung
-t
oder-T
Option fürcp
,mv
,ln
. z.Bcp -t destination_directory source_files …
cp -T source_file destination_file
Beachten Sie, dass
-t
und-T
Gnu-Erweiterungen sind und unter einigen anderen Unixen nicht verfügbar sind. Aus Gründen der Portabilität können Sie anstelle der-t
Option Folgendes tun:cp source_files … destination_directory/
Ich kenne keine alternative sichere Form für
-T
quelle
cp -t
, es ist eine GNU-Erweiterung, die auf BSD-Systemen nicht verfügbar ist. Wenn GNUcoreutils
installiert ist, ist GNUcp
möglicherweise als verfügbargcp
.set -e
in der Sub-Shell funktioniert super, danke! Vielen Dank auch für die Sicherheitshinweise.set -e
nicht in der Berufungshell