Pourquoi la «she-bang» commence-t-elle par un «#!»?

10

Pourquoi la "she-bang" commence-t-elle par #!, comme #!/bin/bash? J'ai toujours accepté que c'est ainsi que cela se fait, mais y a-t-il une raison derrière cela?

Pourquoi commencer par #; n'est-ce pas habituellement un commentaire? Ou est-ce le point qu'il faudrait commenter?

Johan
la source
4
Wikipédia a une histoire assez détaillée #!(autant que dmr s'en souvient…), y compris une explication de la raison pour laquelle #(oui, la ligne a dû être ignorée par les obus existants).
Gilles 'SO- arrête d'être méchant'
Oublié de vérifier wikipedia :)
Johan
1
Je souhaite juste que les coquilles soient assez intelligentes pour dépouiller un CR / LF étranger s'il est là ...;)
Aaron D. Marasco

Réponses:

16

En règle générale, shebang se réfère uniquement à #!( !est généralement appelé "bang", et il semble que "elle" soit une corruption de "SHArp" ou de "haSH" pour #) - toute la ligne est appelée une ligne de shebang

Il commence intentionnellement par un caractère de commentaire pour une compatibilité descendante avec des choses qui ne savent pas comment le gérer; le !est probablement pour le distinguer d'un commentaire aléatoire démarrant le fichier, donc un fichier qui commence par # this is my script!n'essaie pas d'exécuter l' this is my script!interpréteur

Michael Mrozek
la source
2
Bang !est souvent utilisé dans d'autres contextes pour indiquer une commande à exécuter. Par exemple, dans vimou dans d' autres programmes avec leurs propres lignes de commande, bang est souvent le caractère d'échappement qui les fait exécuter la commande dans un shell système au lieu de leur interface interne.
Caleb
4

Pour comprendre cela, vous devez comprendre que la première ligne du script est en fait lue deux fois , par 2 programmes différents. La première fois, le noyau ouvre le fichier et recherche cette séquence de caractères ( #!) sur la première ligne. S'il le trouve, il exécute le programme shell qui y est indiqué, en passant le nom de fichier en paramètre. (par exemple, si le fichier /home/me/foocommence par #!/bin/sh, le noyau s'exécutera /bin/sh /home/me/foo).

Ensuite, le shell ( bin/shou le programme d'interprétation spécifié) lit le fichier. Le shell ne sait rien des lignes de shebang mais il lira toujours la première ligne car il ressemble à n'importe quelle autre ligne du fichier ... il les lit toutes. Vous ne voulez pas que le shell plante ou modifie son comportement de quelque manière que ce soit ... la façon de le faire est de le faire traiter comme un commentaire et de l'ignorer. Ainsi, le meilleur caractère pour commencer une instruction du noyau serait le caractère de commentaire.

JoelFan
la source
Est-ce vraiment le noyau qui fait cela, on dirait que c'est le shell actuel dans lequel vous travaillez qui analysera le shebang puis poussera le script
Johan
Non ... c'est le noyau lui-même, en direct et en personne. Cela fonctionnera même si vous n'utilisez pas un shell pour exécuter le script ... il existe d'autres façons d'exécuter un fichier en plus d'un shell ... par exemple à partir d'un programme C, en utilisant l'appel système "exec"
JoelFan
en.wikipedia.org/wiki/Shebang_(Unix)#Magic_number "#!" en ascii correspond aux octets 0x23 0x21 - lorsque exec () voit ces octets, le comportement consiste à traiter le reste de la ligne comme un chemin vers un interpréteur.
Aaron McMillin
1

Il doit s'agir d'un commentaire, car de cette manière uniquement, il fonctionnera également pour exécuter un script tel que "interprétername scriptname". Je ne connais pas l'origine du "!".

Sven Geggus
la source
1
Même si vous exécutez simplement ./scriptname, l'interpréteur voit toujours la ligne she-bang, elle doit donc toujours être un commentaire.
psusi
1
Ou pour être plus détaillé: le shebang: '#!' est conçu pour ne pas être vu par l'interpréteur - il doit donc commencer par le caractère char '#'. Au lieu de cela, il est «vu» (et interprété) par l'ensemble d'appels système «exec [lv] *» du noyau.
arielf