La exec
chiamata di sistema del kernel Linux comprende #!
nativamente shebangs ( )
Quando fai su bash:
./something
su Linux, questo chiama la exec
chiamata di sistema con il percorso ./something
.
Questa riga del kernel viene chiamata sul file passato a exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Legge i primissimi byte del file e li confronta con #!
.
Se il confronto è vero, il resto della riga viene analizzato dal kernel Linux, che effettua un'altra exec
chiamata con percorso /usr/bin/env python
e file corrente come primo argomento:
/usr/bin/env python /path/to/script.py
e questo funziona con qualsiasi linguaggio di scripting che utilizza #
come carattere di commento.
E sì, puoi fare un ciclo infinito con:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash riconosce l'errore:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
sembra essere leggibile dall'uomo, ma non è necessario.
Se il file si avviava con byte diversi, la exec
chiamata di sistema utilizzava un gestore diverso. L'altro gestore incorporato più importante è per i file eseguibili ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 che verifica la presenza di byte 7f 45 4c 46
(che risulta essere umano leggibile per .ELF
). Confermiamo leggendo i primi 4 byte di /bin/ls
, che è un eseguibile ELF:
head -c 4 "$(which ls)" | hd
produzione:
00000000 7f 45 4c 46 |.ELF|
00000004
Quindi quando il kernel vede quei byte, prende il file ELF, lo mette in memoria correttamente e avvia un nuovo processo con esso. Vedi anche: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Infine, puoi aggiungere i tuoi gestori shebang con il binfmt_misc
meccanismo. Ad esempio, è possibile aggiungere un gestore personalizzato per i .jar
file . Questo meccanismo supporta anche i gestori per estensione del file. Un'altra applicazione è eseguire in modo trasparente eseguibili di un'architettura diversa con QEMU .
Non penso che POSIX specifichi shebangs, tuttavia: https://unix.stackexchange.com/a/346214/32558 , anche se lo menziona nelle sezioni logiche e nella forma "se gli script eseguibili sono supportati dal sistema qualcosa può succedere ".
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