Der exec
Systemaufruf des Linux-Kernels versteht shebangs ( #!
) nativ
Wenn Sie auf Bash machen:
./something
Unter Linux ruft dies den exec
Systemaufruf mit dem Pfad auf ./something
.
Diese Zeile des Kernels wird in der Datei aufgerufen, die an folgende Adresse weitergeleitet wird exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Es liest die allerersten Bytes der Datei und vergleicht sie mit #!
.
Wenn der Vergleich wahr ist, wird der Rest der Zeile vom Linux-Kernel analysiert, der einen weiteren exec
Aufruf mit Pfad /usr/bin/env python
und aktueller Datei als erstes Argument ausführt:
/usr/bin/env python /path/to/script.py
Dies funktioniert für alle Skriptsprachen, die #
als Kommentarzeichen verwendet werden.
Und ja, Sie können eine Endlosschleife machen mit:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash erkennt den Fehler:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
Zufällig ist es für Menschen lesbar, aber das ist nicht erforderlich.
Wenn die Datei mit unterschiedlichen Bytes gestartet exec
würde, würde der Systemaufruf einen anderen Handler verwenden. Der andere wichtigste integrierte Handler ist für ausführbare ELF-Dateien: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, der nach Bytes sucht 7f 45 4c 46
(was zufällig auch menschlich ist) lesbar für .ELF
). Lassen Sie uns das bestätigen, indem wir die 4 ersten Bytes von lesen /bin/ls
, bei denen es sich um eine ELF-ausführbare Datei handelt:
head -c 4 "$(which ls)" | hd
Ausgabe:
00000000 7f 45 4c 46 |.ELF|
00000004
Wenn der Kernel diese Bytes sieht, nimmt er die ELF-Datei, speichert sie korrekt und startet damit einen neuen Prozess. Siehe auch: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Schließlich können Sie mit dem binfmt_misc
Mechanismus Ihre eigenen Shebang-Handler hinzufügen . Beispielsweise können Sie einen benutzerdefinierten Handler für .jar
Dateien hinzufügen . Dieser Mechanismus unterstützt sogar Handler nach Dateierweiterung. Eine andere Anwendung besteht darin , ausführbare Dateien einer anderen Architektur transparent mit QEMU auszuführen .
Ich glaube jedoch nicht, dass POSIX Shebangs spezifiziert: https://unix.stackexchange.com/a/346214/32558 , obwohl es dies in Begründungsabschnitten und in der Form "Wenn ausführbare Skripte vom System unterstützt werden" erwähnt könnte passieren".
chmod +x my_shell_script.sh ; /path/to/my_shell_script.sh # or ./my_shell_script.sh if you happen to be in its directory