Warum beginnt der "She-Bang" mit einem "#!"?

10

Warum beginnt die "She-Bang" mit einem #!, wie #!/bin/bash? Ich habe immer akzeptiert, dass dies so gemacht wird, aber gibt es einen Grund dafür?

Warum anfangen mit #; Ist das nicht normalerweise ein Kommentar? Oder ist es der Punkt, dass es ein Kommentar sein sollte?

Johan
quelle
4
Wikipedia hat eine ziemlich detaillierte Geschichte von #!(so viel sich dmr erinnert…), einschließlich einer Erklärung, warum die #(ja, die Linie musste von vorhandenen Muscheln ignoriert werden).
Gilles 'SO - hör auf böse zu sein'
Verpasst, um Wikipedia zu überprüfen :)
Johan
1
Ich wünschte nur, die Muscheln wären klug genug, um ein fremdes CR / LF zu entfernen, wenn es da ist ...;)
Aaron D. Marasco

Antworten:

16

Typischerweise bezieht sich shebang nur auf das #!( !wird normalerweise "bang" genannt, und es sieht so aus, als ob "she" eine Verfälschung von "SHArp" oder "haSH" ist #) - die gesamte Linie wird shebang-Linie genannt

Es beginnt absichtlich mit einem Kommentarzeichen, um die Abwärtskompatibilität mit Dingen zu gewährleisten, die nicht wissen, wie sie damit umgehen sollen. Das !ist vermutlich nur, um es von einem zufälligen Kommentar zu unterscheiden, der die Datei startet, sodass eine Datei, die mit beginnt, # this is my script!nicht versucht, den this is my script!Interpreter auszuführen

Michael Mrozek
quelle
2
Bang !wird häufig in anderen Kontexten verwendet, um einen auszuführenden Befehl anzugeben. Zum Beispiel in vimoder anderen Programmen mit eigenen Befehlszeilen ist Bang oft das Escape-Zeichen, mit dem sie den Befehl in einer System-Shell anstelle ihrer internen Schnittstelle ausführen.
Caleb
4

Um dies zu verstehen, müssen Sie erkennen, dass die erste Zeile des Skripts tatsächlich zweimal von zwei verschiedenen Programmen gelesen wird . Beim ersten Mal öffnet der Kernel die Datei und sucht #!in der ersten Zeile nach dieser Zeichenfolge ( ). Wenn es es findet, führt es das dort angegebene Shell-Programm aus und übergibt den Dateinamen als Parameter. (zB wenn die Datei mit /home/me/foobeginnt #!/bin/sh, wird der Kernel ausgeführt /bin/sh /home/me/foo).

Als nächstes bin/shliest die Shell ( oder welches Interpreter-Programm auch immer angegeben wurde) die Datei. Die Shell weiß nichts über Shebang-Zeilen, liest aber trotzdem die erste Zeile, da sie genau wie jede andere Zeile in der Datei ist ... sie liest sie alle. Sie möchten nicht, dass die Shell abstürzt oder ihr Verhalten in irgendeiner Weise ändert. Die Vorgehensweise besteht darin, sie als Kommentar zu behandeln und zu ignorieren. Das beste Zeichen für einen Kernel-Befehl wäre daher das Kommentarzeichen.

JoelFan
quelle
Ist es wirklich der Kernel, der das tut? Es klingt so, als ob es die aktuelle Shell ist, in der Sie arbeiten, die den Shebang analysiert und dann das Skript pusht
Johan
Nein ... es ist der Kernel selbst, live und persönlich. Es funktioniert auch dann, wenn Sie keine Shell zum Ausführen des Skripts verwenden. Neben einer Shell gibt es noch andere Möglichkeiten, eine Datei auszuführen. Zum Beispiel aus einem C-Programm mit dem Systemaufruf "exec"
JoelFan
en.wikipedia.org/wiki/Shebang_(Unix)#Magic_number "#!" in ascii sind die Bytes 0x23 0x21 - wenn exec () diese Bytes sieht, wird der Rest der Zeile als Pfad zu einem Interpreter behandelt.
Aaron McMillin
1

Es muss ein Kommentar sein, da nur so auch ein Skript wie "Interpretername Skriptname" ausgeführt werden kann. Ich weiß nicht über den Ursprung des "!".

Sven Geggus
quelle
1
Selbst wenn Sie nur ./scriptname ausführen, sieht der Interpreter immer noch die She-Bang-Zeile, sodass es sich immer noch um einen Kommentar handeln muss.
Psusi
1
Oder genauer gesagt: der Schebang: '#!' ist so konzipiert, dass es vom Interpreter nicht gesehen wird - daher muss es mit dem Kommentar char '#' beginnen. Stattdessen wird es vom Kernel 'exec [lv] *' von Systemaufrufen 'gesehen' (und interpretiert).
Arielf