Ich verwende ein Bash-Skript im Terminal und beende es bei einem Fehler mit
set -o errexit
bricht mein Terminal ab, was EXTREM ÄRGERLICH ist, weil ich das Terminal schließen, ein anderes öffnen und einige Variablen zurücksetzen muss.
Bisher mit
command || return
lines macht im script genau das, was ich will
set -o errexit
zu tun ... Aber ich möchte, dass es für das gesamte Drehbuch getan wird; nicht nur eine Zeile / Befehl
Ich habe eine Datei mit Befehlen zum Einrichten einer Site, und ich möchte lieber keinen Befehl || ausführen Rückkehr
für jede einzelne Zeile in der Datei
Gibt es eine andere festgelegte Option oder etwas anderes, das einfach "zurückkehrt", anstatt das Terminal zu verlassen?
- Aus Gründen der Übersichtlichkeit möchte ich das Skript beenden und das Terminal in dem Zustand belassen, in dem das Drücken von Strg + C zum Beenden eines im Terminal ausgeführten Dienstes ausgeführt wird. command || return
tut das. Aber ich möchte nicht auf || return
jede Zeile in der Datei eingehen. Ich suche also nach etwas ähnlichem set -o errexit
, das nicht dazu führt, dass das Terminal heruntergefahren wird
--- Hinweis: Erstellen Sie ein dummes Skript mit zwei Zeilen (super.sh):
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
Und set -o errexit
an der Spitze von create.sh platzieren,
funktioniert genau so wie ich es erwarte. Es ist jedoch wirklich dumm, eine Datei mit zwei Zeilen darin zu erstellen, nur um ein anderes Bash-Skript aufzurufen, anstatt es nur vom Terminal aus aufzurufen. Ugghhh
Hier sind einige Beispiele:
in super.sh
#!/bin/bash
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
in create.sh
#!/bin/bash
set -o errexit
#line below this is a line that fails and will cause the script to stop and return to the terminal as expected
sed "s/@@SITE_NAME@@/$dirname"
~/Desktop/site_builder/template_files/base.html > ~/Desktop/$dirname/templates/base.html # a line with a stupid error
im terminal:
$ bash super.sh
Ausgabe wie erwartet:
my-mac$
Das funktioniert. Was für eine nervige Lösung.
Ich möchte im Idealfall ausführen, was in der dummen Datei super.sh vom Terminal ist, nicht in der Datei super.sh: D, ohne dass das Terminal mich herunterfährt. Das passiert mit dem, was ich versuche:
Terminalbefehl:
my-mac$ source $create_path blah
in create.sh habe ich noch set -o errexit
Hier ist die Ausgabe auf dem Terminal
sed: 1: "s/@@SITE_NAME@@/blah": unterminated substitute in regular expression
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
Und dann ist das Terminal eingefroren. Strg + C funktioniert nicht, ebenso wenig wie Strg + D
Wenn set -o errexit
ich stattdessen nur command || return
Anweisungen überall in der Datei create.sh verwende, erhalte ich genau das, was ich will, während ich die Zeilen in supser.sh direkt auf dem Terminal ausführe (anstatt super.sh vom Terminal aus aufzurufen). Aber das ist auch keine praktische Lösung.
Hinweis: Ich mochte die Antwort von @terdon, dass ich nur eine untergeordnete Shell erzeugt habe, und habe am Ende nur eine untergeordnete Shell über das Skript anstelle des Terminals erzeugt, wie er in seiner Antwort mit geschweiften Klammern ( )
um das gesamte Skript herum gezeigt hat funktioniert auch.
source $file_path argument
Das Skript wird in derselben Shell ausgeführt, von der ich es aufgerufen habe (wassource
mir gesagt wurde ... und es verhält sich so).command || return
Anweisungen befinden sich in der Datei, die ich im Terminal ausführeAntworten:
Quell die Datei einfach mit einem Failsafe:
... dann wird der Gesamtbefehl nicht fehlschlagen, auch wenn dies der
source
Fall ist.quelle
source file || true
tut dies nicht und auch nicht,source file || return
wenn ich dies in das TerminalJills-MBP:~ jillr$ source ~/Desktop/site_builder/create.sh blah || true
Es führt einfach den nächsten Teil des Skripts bei einem Fehler aus, also kehrt es zurück anstatt wahr. Das einzige, was funktioniert hat, sindcommand || return
Anweisungen in der eigentlichen Datei für alle Befehle, was albern ist. Ich weiß nicht, ob es auch etwas nützen würde, wenn man alles in eine Funktion wirft undfunction || return
am Ende der Datei aufruft .|| return
einen Befehl eingeben, der fehlschlägt, wird das Ja zurückgegeben. Ich dachte, wir versuchen, Ihre Haupt- / Eltern-Shell am Beenden zu hindern?Dies ist das einzige, was für das, was ich tun musste, funktioniert (Erstellen einer virtuellen Umgebung, Aktivieren und Installieren der Anforderungen mithilfe eines Bash-Skripts):
Erzeugen einer Subshell / Child-Shell aus dem Skript, wie in:
stupid_file.sh
führe die stupid_file aus mit:
DAS ENDE.
** Verbeugt sich **
(Dank geht an Jeff und Terdon)
quelle
bash $create_path blah
und zu sehen, ob es immer noch beendet wird, auf die gleiche Weise ausgeführt wird und weiterhin alles korrekt in meine virtuelle Umgebung installiert. Keine Zeit mehr.(...)
, da alle Zuweisungen in Klammern nur diese Subshell betreffen.foo=3; (foo=5); echo "$foo"
wird 3, nicht 5source file
vom Terminal aus anrufen und die gleichen Ergebnisse erwarten. Weil das nie geklappt hat. Das einzige Mal, dass ich die gleichen Ergebnisse erhalte, ist das explizite Erstellen einer Sub-Shell, ob über das Terminal oder über das Skript. Ich kann jedochbash
anstelle von verwendensource
, um das Skript auszuführen und die gleichen Ergebnisse zu erhalten, aber nur, wenn ich mein Skript in einer Sub-Shell explizit ausführepip install -r $apath/requirements.txt
in dieser aktivierten Umgebung ausführen . Es ist , warum ich Quelle in erster Linie verwendet , um das Skript aufrufenAls einfache Umgehung können Sie eine Shell in Ihrer aktuellen Shell und Quelle ausführen. Etwas wie:
Öffnen Sie ein neues Terminal und richten Sie alles nach Ihren Wünschen ein. Sie haben einige Umgebungsvariablen und dergleichen erwähnt. Stellen Sie sie hier auf.
Starten Sie in diesem Terminal eine neue Shell. Zum Beispiel
bash
.Mach dein Ding. Geben Sie Ihr Skript als Quelle ein. Wenn es beendet wird, werden Sie einfach in die erste Shell geworfen und alles ist noch eingerichtet. Laufen
bash
Sie einfach noch einmal und Sie sind wieder im Geschäft.Zur Veranschaulichung habe ich dieses Skript erstellt, das fehlschlägt, wenn Sie versuchen, es als Quelle zu verwenden:
Mal sehen, was passiert, wenn ich eine verschachtelte Shell-Sitzung starte und sie dann als Quelle benutze (beachte, dass ich den portablen Namen für den
source
Befehl verwende.
;source
ist ein Bashismus):Wie Sie sehen, führte der Syntaxfehler zum Beenden des Quell-Skripts, was wiederum dazu führte, dass meine Shell-Sitzung beendet wurde. Da es sich jedoch um eine verschachtelte Sitzung handelte, landete ich gerade wieder in der ursprünglichen übergeordneten Shell, in der alle Variablen noch eingerichtet waren . Führen Sie jetzt einfach erneut eine neue Shell aus, und Sie können zur Suche nach Ihrem Skript zurückkehren.
quelle
create_path=~/Desktop/site_builder/create.sh
in die übergeordnete Shell, weil ich das so oft mache. Und ich brauche es, um die Quelle $ create_path [Argument] aufzurufen, um das Skript auszuführen.export
. Aber was Sie beschreiben, macht wirklich wenig Sinn. Es klingt immer mehr nach einem XY-Problem . Vielleicht möchten Sie eine neue Frage stellen, in der erläutert wird, was Ihr Endziel ist. Ich wette, wir können Ihnen eine bessere Lösung für all diese seltsamen Beschaffungen anbieten.