Warum müssen Sie #! / Bin / bash am Anfang einer Skriptdatei einfügen?

486

Ich habe schon einmal Bash- Skripte erstellt und alle liefen #!/bin/basham Anfang ohne .

Was bringt es, es einzubauen? Würden die Dinge anders sein?

Wie spricht man auch aus #? Ich weiß, dass !das als "Knall" ausgesprochen wird.

Wie wird #!ausgesprochen?

Knoten Ninja
quelle
8
Sie müssen und sollten nicht, es sei denn, Sie haben keine Wahl. Verwenden Sie '#! / Bin / sh', solange Sie können, und lernen Sie den Unterschied zwischen einer (POSIX) Shell und Bash kennen. Es wird einen Tag dauern, bis Ihr Lebenslauf zu lange wächst, wenn Sie sich auf einem System mit einer anderen Shell befinden und Ihre Skripte weiterhin funktionieren sollen.
Jens
50
Es wird "Hash-Bang" oder "She-Bang" ausgesprochen.
Beachhouse
22
Ich denke, es ist erwähnenswert, dass dies nur ausgeführt wird, wenn Sie Ihr Skript als ausführbare Datei ausführen. Wenn Sie also das Flag ./yourscript.extensionfür ausführbare Dateien setzen und dann beispielsweise ./helloworld.pyoder ./helloworld.sheingeben, wird in dieser obersten Zeile nach dem Interpreter gesucht. Dies ist #!/bin/pythonoder !#/bin/bash, während bei der Ausführung des Skripts python helloworld.pydie erste Zeile nicht beobachtet wird, da sie kommentiert ist aus. Es ist also eine spezielle Sequenz für die Shell / den Kernel.
JFA
@JFA gibt es eine Änderung in der Reihenfolge zwischen Bash und Python, wenn! # Für Python und #! für Bash?
AAI
1
@ AjeyaAnand nein, es war ein Fehler, guter Fang
JFA

Antworten:

426

Es ist eine Konvention, damit die * nix-Shell weiß, welche Art von Interpreter ausgeführt werden soll.

Beispielsweise waren ältere ATT- Varianten standardmäßig sh (die Bourne-Shell), während ältere BSD-Versionen standardmäßig csh (die C-Shell) waren.

Auch heute (wo die meisten Systeme bash laufen, die "Bourne Again Shell" ) kann, Skripte in bash sein, Python, Perl, Rubin, PHP, etc, etc. Zum Beispiel könnten Sie sehen , #!/bin/perloder #!/bin/perl5.

PS: Das Ausrufezeichen ( !) heißt liebevoll "Knall" . Das Shell-Kommentarsymbol ( #) wird manchmal als "Hash" bezeichnet .

PPS: Denken Sie daran - unter * nix ist das Zuordnen eines Suffix zu einem Dateityp lediglich eine Konvention , keine "Regel" . Eine ausführbare Datei kann ein Binärprogramm sein, einer von einer Million Skripttypen und andere Dinge. Daher die Notwendigkeit für #!/bin/bash.

paulsm4
quelle
1
Ich habe etwas anderes Nützliches herausgefunden, $ #. Wie heißt das?
Knoten Ninja
91
Der Shebang ist keine Shell- Konvention, er wird vom Kernel bei der Verarbeitung des execve(2)Systemaufrufs interpretiert . Der Shebang ist also eine Kernel- Konvention, keine Shell-Konvention.
Basile Starynkevitch
10
Außerdem hilft es einigen Editoren wie Vim, die Sprache für die Syntaxhervorhebung zu bestimmen, wenn die Datei keine Erweiterung hat. Ohne den Shebang zeigt Vim ein Bash-Skript an, das mit einer einfachen Textdatei identisch ist.
Aaron Blenkush
1
Ich frage mich, ob Sie #!/bin/shDinge wie .profileund Dinge hinzufügen müssen , die unter Last laufen
Kolob Canyon
5
Also ... Hash-Bang-Slash-Bin-Slash-Bash ?
Bernat
134

Genauer gesagt wird der Shebang#! , wenn es sich um die ersten zwei Bytes einer ausführbaren ( x Modus- ) Datei handelt, vom Systemaufruf execve (2) (der Programme ausführt) interpretiert . Aber die POSIX-Spezifikation fürexecve erwähnt den Shebang nicht.

Es muss ein Dateipfad einer ausführbaren Interpreter-Datei folgen (der übrigens sogar relativ sein kann, aber meistens absolut ist).

Ein netter Trick (oder vielleicht nicht so netter ), um einen Interpreter (zB python) im Benutzer zu finden, $PATHist die Verwendung des envProgramms (immer unter /usr/bin/envLinux) wie z

 #!/usr/bin/env python

Jede ausführbare ELF-Datei kann ein Interpreter sein. Sie könnten sogar verwenden #!/bin/catoder #!/bin/truewenn Sie wollten! (aber das wäre oft nutzlos)

Basile Starynkevitch
quelle
8
In dieser Frage finden Sie eine Diskussion des #!/usr/bin/envHacks.
Keith Thompson
Wenn ich ein Argument an Python übergeben möchte, wie mache ich das eigentlich, das ich ausführen möchte #!/usr/bin/env bash -x. Wie mache ich das ?
Indianwebdevil
Es ist einfach, ich habe es selbst gefunden, füge einfach den Parameter danach hinzu#!/usr/bin/env bash -x
indianwebdevil
bashist fast immer /bin/bashso, dass Ihr Schebang sein sollte#!/bin/bash -x
Basile Starynkevitch
49

Es heißt Shebang . In Unix-Sprache heißt # scharf (wie in der Musik) oder Hash (wie Hashtags auf Twitter) und! heißt Knall. (Sie können Ihren vorherigen Shell-Befehl tatsächlich mit !! referenzieren, genannt Bang-Bang). Zusammen ergibt sich also haSH-BANG oder Shebang.

Der Teil nach dem #! teilt Unix mit, welches Programm zum Ausführen verwendet werden soll. Wenn es nicht angegeben ist, wird es mit bash (oder sh oder zsh oder was auch immer Ihre $ SHELL-Variable ist) versucht, aber wenn es dort ist, wird es dieses Programm verwenden. Außerdem ist # in den meisten Sprachen ein Kommentar, sodass die Zeile bei der nachfolgenden Ausführung ignoriert wird.

austin1howard
quelle
2
Wenn ich bereits in Bash bin, startet es eine weitere Bash-Instanz, wenn #! / Bin / bash angezeigt wird? Was ist, wenn ich schon in Bash bin und es weglasse? Gibt es einen Unterschied?
Knoten Ninja
2
@javascriptninja so oder so startet es eine neue Bash-Shell. Im Fall von Bash gibt es wirklich keinen Unterschied, solange Sie Bash bereits verwenden. Der Shebang ist nur dann wirklich wichtig, wenn (a) Sie in etwas laufen müssen, das nicht nur eine Shell ist, wie Python oder Perl, oder (b) Sie die Bash-Shell nicht verwenden (dh Sie verwenden zsh), aber Sie müssen Führen Sie etwas aus, das in Bash ausgeführt werden muss.
austin1howard
Meiner Meinung nach ist es jedoch empfehlenswert, den Shebang einzubeziehen, damit jemand, der den Code liest, weiß, was los ist.
austin1howard
2
Falsch: execve(2)syscall verwendet die $SHELLVariable nicht. Es ist der Kernel, der den Shebang interpretiert.
Basile Starynkevitch
1
@BasileStarynkevitch das ist richtig, der Elfenlader im Kernel interpretiert den Shebang. Ich sagte, dass $ SHELL verwendet werden würde, wenn kein Shebang bereitgestellt würde.
austin1howard
19

Der Shebang ist eine Anweisung an den Loader, das Programm zu verwenden, das nach dem #!als Interpreter für die betreffende Datei angegeben ist, wenn Sie versuchen, es auszuführen. Also, wenn Sie versuchen , eine Datei mit dem Namen laufen zu lassen , foo.shdas hat #!/bin/bashan der Spitze, den eigentlichen Befehl, der ausgeführt ist /bin/bash foo.sh. Dies ist eine flexible Möglichkeit, verschiedene Interpreter für verschiedene Programme zu verwenden. Dies wird auf Systemebene implementiert, und die API auf Benutzerebene ist die Shebang-Konvention.

Es ist auch wichtig zu wissen, dass der Shebang eine magische Zahl ist - eine von Menschen lesbare Zahl , die die Datei als Skript für den angegebenen Interpreter identifiziert.

Ihr Punkt, dass es auch ohne den Shebang "funktioniert", ist nur, weil das fragliche Programm ein Shell-Skript ist, das für dieselbe Shell geschrieben wurde wie die, die Sie verwenden. Zum Beispiel könnten Sie sehr gut eine Javascript-Datei schreiben und dann eine #! /usr/bin/js(oder etwas Ähnliches) einfügen, um ein Javascript "Shell-Skript" zu haben.

Noufal Ibrahim
quelle
18

Das Betriebssystem verwendet die Standard-Shell, um Ihr Shell-Skript auszuführen. Wenn Sie also den Shell-Pfad am Anfang des Skripts erwähnen, bitten Sie das Betriebssystem, diese bestimmte Shell zu verwenden. Es ist auch nützlich für die Portabilität .

Balaswamy Vaddeman
quelle
15

Jede Distribution hat eine Standard-Shell. Bash ist die Standardeinstellung auf den meisten Systemen. Wenn Sie zufällig auf einem System mit einer anderen Standard-Shell arbeiten, funktionieren die Skripte möglicherweise nicht wie beabsichtigt, wenn sie speziell für Bash geschrieben wurden.

Bash hat sich im Laufe der Jahre weiterentwickelt und Code von kshund übernommen sh.

Wenn Sie #!/bin/bashals erste Zeile Ihres Skripts hinzufügen, wird das Betriebssystem angewiesen, die angegebenen shellBefehle aufzurufen , um die im Skript folgenden Befehle auszuführen.

#! wird oft als "Hash-Bang", "She-Bang" oder "Sha-Bang" bezeichnet.

jaypal singh
quelle
9

Es heißt Shebang . Es besteht aus einem Zahlenzeichen und einem Ausrufezeichen (#!), Gefolgt vom vollständigen Pfad zum Interpreter wie / bin / bash. Alle Skripte unter UNIX und Linux werden mit dem in der ersten Zeile angegebenen Interpreter ausgeführt.

Uday Sawant
quelle
0

Dies kann für jemanden nützlich sein, der ein anderes System verwendet, für das diese Bibliothek nicht verfügbar ist. Wenn dies nicht deklariert ist und Sie einige Funktionen in Ihrem Skript haben, die von diesem System nicht unterstützt werden, sollten Sie # / bin / bash deklarieren. Ich bin vor der Arbeit auf dieses Problem gestoßen, und jetzt füge ich es nur als Übung hinzu.

Beardy
quelle