L' exec
appel système du noyau Linux comprend shebangs ( #!
) de manière native
Quand vous faites sur bash:
./something
sous Linux, cela appelle l' exec
appel système avec le chemin ./something
.
Cette ligne du noyau est appelée sur le fichier transmis à exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
Il lit les tout premiers octets du fichier et les compare à #!
.
Si la comparaison est vraie, alors le reste de la ligne est analysé par le noyau Linux, qui effectue un autre exec
appel avec le chemin /usr/bin/env python
et le fichier en cours comme premier argument:
/usr/bin/env python /path/to/script.py
et cela fonctionne pour tout langage de script utilisant #
un caractère de commentaire.
Et oui, vous pouvez faire une boucle infinie avec:
printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a
Bash reconnaît l'erreur:
-bash: /a: /a: bad interpreter: Too many levels of symbolic links
#!
se trouve simplement lisible par l’homme, mais ce n’est pas nécessaire.
Si le fichier a démarré avec différents octets, l' exec
appel système utilisera un autre gestionnaire. L’autre gestionnaire intégré le plus important concerne les fichiers exécutables ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305, qui vérifie la présence d’octets 7f 45 4c 46
(qui se trouve également être humain). lisible pour .ELF
). Confirmons cela en lisant les 4 premiers octets de /bin/ls
, qui est un exécutable ELF:
head -c 4 "$(which ls)" | hd
sortie:
00000000 7f 45 4c 46 |.ELF|
00000004
Ainsi, lorsque le noyau voit ces octets, il prend le fichier ELF, le met correctement en mémoire et lance un nouveau processus avec celui-ci. Voir aussi: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
Enfin, vous pouvez ajouter vos propres gestionnaires Shebang avec le binfmt_misc
mécanisme. Par exemple, vous pouvez ajouter un gestionnaire personnalisé pour les .jar
fichiers . Ce mécanisme prend même en charge les gestionnaires par extension de fichier. Une autre application consiste à exécuter de manière transparente des exécutables d’une architecture différente avec QEMU .
Cependant, je ne pense pas que POSIX spécifie des shebangs: https://unix.stackexchange.com/a/346214/32558 , bien qu'il le mentionne dans les sections de justification, et sous la forme "si les scripts exécutables sont pris en charge par le système Pourrait arriver".
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