Bash Shebang für Dummies?

36

Ich habe einige Bash-Skripte, die ich eingerichtet habe und die meistens verwenden

#!/bin/bash

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

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

und so weiter.

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

coneybeare
quelle
Diese Optionen gelten nur für Bash (oder einen anderen Interpreter). Sie können für andere Shells (beispielsweise dash und ksh) identisch sein, für andere Interpreter wie AWK und Python jedoch unterschiedlich. Sie können viele der Optionen verwenden, die der Interpreter akzeptiert. Die Optionen sind interpreterspezifisch, während der Shebang ein Kernel-Feature ist.
Bis auf weiteres angehalten.

Antworten:

41

Beginnt ein Skript /path/to/foomit #!/bin/bash, /path/to/foo arg1 arg2entspricht die Ausführung der Ausführung /bin/bash /path/too/foo arg1 arg2. Wenn die Shebang-Linie ist #!/bin/bash -ex, ist es gleichbedeutend mit der Ausführung /bin/bash -ex /path/too/foo arg1 arg2. Diese Funktion wird vom Kernel verwaltet.

Beachten Sie, dass Sie möglicherweise nur ein Argument in der shebang-Zeile haben: Einige Unices (wie z. B. Linux) akzeptieren nur ein Argument. Dies #!/bin/bash -e -xwürde dazu führen, dass bash das einzige fünfstellige Argument -e -x(ein Syntaxfehler) anstelle von zwei Argumenten -eund empfängt -x.

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

  • -e bedeutet, dass das Skript sofort beendet wird, wenn ein Befehl fehlschlägt (was durch Zurückgeben eines Nicht-Null-Status angezeigt wird).
  • -x Bewirkt, dass die Shell einen Ausführungs-Trace ausgibt.

Andere Programme verstehen diese Optionen möglicherweise, haben jedoch andere Bedeutungen.

Gilles 'SO - hör auf böse zu sein'
quelle
24

Sie sind Optionen übergeben bashsiehe help setfür weitere Informationen, 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.
cYrus
quelle
3
+1 Und -exmacht beides
Nifle
Es ist verwirrend, weil sie wie Befehlszeilenoptionen aussehen, die an Bash übergeben werden.
Caoilte
2
@Caoilte: Und in der Tat sind sie (aus man bash): In addition to the single-character shell options documented in the description of the set builtin command, bash interprets the following options when it is invoked: [...].
CYRUS
1
arrgh! blinzeln und du vermisst es! :).
Caoilte
0

Ich möchte nur eine noch bessere - wie auch tragbarere - Alternative erwähnen:

#!/usr/bin/env bash

Das obige Beispiel verwendet env, um die bashausführbare Datei zu finden , die nicht immer auf ist /bin/bash. Ye Olde #!/bin/bashSkripte funktionieren nicht auf NixOS , zum Beispiel.

Wenn Sie envwie oben gezeigt verwenden, können Sie (soweit mir bekannt) kein Argument wie -eto bashangeben. Aber Sie können dies stattdessen tun:

#!/usr/bin/env bash
set -e
Simon Alling
quelle
2
Ich mache das die ganze Zeit, aber ich würde nicht sagen, dass es "portabler" ist - in der Tat ist das Risiko, dass der Benutzer etwas völlig anderes ausführt (als man es von einem System erwarten kann, mit dem es ausgeliefert wird), viel größer. Beispielsweise
liefert
Ja, die envVerwendung ist besonders für Skripte, die Python ausführen, nicht gut, da Sie einfach nicht wissen, ob die Standardversion python2 oder 3 ist, und das macht einen großen Unterschied für Skripte, die eine bestimmte Version benötigen. Besser explizit als schlau
smac89