Bash Shebang für Dummies?

Bash Shebang für Dummies?

Ich habe einige Bash-Skripte eingerichtet, die hauptsächlich verwenden

#!/bin/bash

aber ich stoße regelmäßig auf welche, die aussehen wie

#!/bin/bash -e
#!/bin/bash -x
#!/bin/bash -ex

und so weiter.

Kann jemand die Bedeutung und Vorteile dieser Shebang-Optionen erklären und ob sie auch für andere Shebangs gelten?

Antwort1

Wenn ein Skript /path/to/foomit beginnt #!/bin/bash, ist die Ausführung /path/to/foo arg1 arg2gleichbedeutend mit der Ausführung von /bin/bash /path/too/foo arg1 arg2. Wenn die Shebang-Zeile lautet #!/bin/bash -ex, ist sie gleichbedeutend mit der Ausführung von /bin/bash -ex /path/too/foo arg1 arg2. Diese Funktion wird vom Kernel verwaltet.

Beachten Sie, dass Sie portabel nur ein Argument in der Shebang-Zeile haben können: Einige Unix-Systeme (wie etwa Linux) akzeptieren nur ein Argument, was #!/bin/bash -e -xdazu führen würde, dass Bash das einzelne fünfstellige Argument -e -x(ein Syntaxfehler) statt zwei Argumente -eund erhält -x.

Für die Bourne-Shell shund abgeleitete Shells wie POSIX sh, bash, ksh und zsh:

  • -ebedeutet, dass das Skript sofort beendet wird, wenn ein Befehl fehlschlägt (was durch die Rückgabe eines Status ungleich Null angezeigt wird).
  • -xbewirkt, dass die Shell einen Ausführungs-Trace druckt.

Andere Programme verstehen diese Optionen möglicherweise, haben aber eine andere Bedeutung.

Antwort2

Es handelt sich um Optionen, die übergeben werden , um weitere Informationen bashanzuzeigen help set. In diesem Fall:

-x  Print commands and their arguments as they are executed.
-e  Exit immediately if a command exits with a non-zero status.

Antwort3

Ich möchte nur eine noch bessere – also portablere – Alternative erwähnen:

#!/usr/bin/env bash

Das obige Beispiel verwendet, envum die bashausführbare Datei zu finden, die nicht immer bei ist /bin/bash. Alte #!/bin/bashSkripte funktionieren nicht aufNixOS, Zum Beispiel.

Wenn Sie envwie oben gezeigt verwenden, können Sie kein Argument wie -eto angeben bash(soweit ich weiß). Aber Sie können stattdessen Folgendes tun:

#!/usr/bin/env bash
set -e

Antwort4

Das Starten eines Skripts mit oder das entsprechende Ausführen von hat dieselbe Wirkung wie das Einfügen innerhalb des Skripts direkt nach seiner Zeile.#! /path/to/bash -optionbash -option /path/to/scriptset -option#!

set -xdient im Wesentlichen nur zum Debuggen. Normalerweise möchten Sie es nicht eingeschaltet lassen.

Die Wirkung set -eist viel komplizierter als es die Anleitung vermuten lässt. Die genauere Beschreibung lautet etwa:

set -eWenn nach dem Aufruf vonungetestetDer Befehl wird mit einem Status ungleich Null beendet. Dadurch wird die Shell mit diesem Beendigungsstatus beendet.

ich sageetwas genauerweil es immer noch ziemlich vage ist: die Liste der Situationen, in denen der Befehl berücksichtigt wirdgeprüftist geheimnisvoll und schwer vorherzusagen. Die genauen Regeln unterscheiden sich zwischen Shells und ändern sich sogar zwischen Versionen derselben Shell.

set -etutnichtBeenden Sie Bash, wenn der Exit-Status eines beliebigen Befehls ungleich Null ist:

  • zwischen if/ elifund then; oder
  • zwischen while/ untilund do; oder
  • folgendes !; oder
  • gefolgt von ||„oder“ &&oder „oder“ &(wobei &das entsprechende wait„oder“ fgfehlschlagen kann); oder
  • gefolgt von |, es sei denn, set -o pipefailes ist wirksam; oder
  • innerhalb $( ... ), wenn es als Teil eines Befehls verwendet wird (keine bloßen Zuweisungen und/oder Umleitungen, was bedeutet, dass es foo=$( bar )fehlschlägt, wenn bares fehlschlägt, aber local foo=$( bar )nicht); oder
  • innerhalb eines zusammengesetzten Befehls, wenn die oben genannten Punkte zutreffen; oder
  • Innerhalb einer Shell-Funktion, die von überall aufgerufen wird, gilt das oben Gesagte.

Die Auswirkungen auf zusammengesetzte Befehle und Shell-Funktionen sind rekursiv.

Da die Shell selbst mit einem Status ungleich Null beendet wird, kann sich der Effekt aus einer Unter-Shell ausbreiten.

Die !Ausnahme gilt auch dann, wenn der invertierte Exit-Status ignoriert wird.

Umgekehrt set -ekönnen Auslöserjeder andereStatus ungleich Null, unabhängig davon, ob er „fehlgeschlagen“ oder einfach „falsch“ bedeutet. Beispielsweise ((x++))hat der Exit-Status ungleich Null „fehlgeschlagen“, wenn xer anfänglich 0 ist.

Weil es so ein Durcheinander ist, gibt es eine Denkschule, die besagt, dass es set -evermieden werden sollte, und stattdessen alle Befehle explizit überprüft werden sollten.

Oder wenn Sie dennoch verwenden möchten set -e, denken Sie daran, !vor alle ((arithmetic))Gruppen zu schreiben.

verwandte Informationen