execWywołanie systemowe jądra Linux rozumie shebangs ( #!) natywnie
Kiedy robisz na bash:
./something
w Linuksie wywołuje to wywołanie execsystemowe ze ścieżką ./something.
Ta linia jądra zostaje wywołana w pliku przekazanym do exec: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Odczytuje pierwsze bajty pliku i porównuje je #!.
Jeśli porównanie jest prawdziwe, reszta linii jest analizowana przez jądro Linuksa, które wykonuje kolejne execwywołanie ze ścieżką /usr/bin/env pythoni bieżącym plikiem jako pierwszym argumentem:
/usr/bin/env python /path/to/script.py
i działa to na każdy język skryptowy, który używa #jako znaku komentarza.
I tak, możesz wykonać nieskończoną pętlę za pomocą:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash rozpoznaje błąd:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#! akurat jest czytelny dla ludzi, ale nie jest to wymagane.
Jeśli plik zaczął się od różnych bajtów, execwywołanie systemowe użyłoby innej procedury obsługi. Innym najważniejszym wbudowanym modułem obsługi są pliki wykonywalne ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, który sprawdza bajty 7f 45 4c 46(które również są ludźmi) czytelne dla .ELF). Potwierdźmy to, czytając 4 pierwsze bajty /bin/ls, czyli plik wykonywalny ELF:
head -c 4 "$(which ls)" | hd
wynik:
00000000 7f 45 4c 46 |.ELF|
00000004
Więc kiedy jądro zobaczy te bajty, pobiera plik ELF, poprawnie zapisuje go w pamięci i rozpoczyna z nim nowy proces. Zobacz także: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Na koniec możesz dodać własne binfmt_miscmechanizmy shebang z mechanizmem. Na przykład możesz dodać niestandardowy moduł obsługi .jarplików . Ten mechanizm obsługuje nawet programy obsługi według rozszerzeń plików. Inną aplikacją jest przezroczyste uruchamianie plików wykonywalnych o innej architekturze za pomocą QEMU .
Nie sądzę jednak, że POSIX określa shebangs: https://unix.stackexchange.com/a/346214/32558 , chociaż wspomina o tym w sekcjach uzasadnienia oraz w formie „jeśli skrypty wykonywalne są obsługiwane przez system, coś może się zdarzyć".
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