Est-ce que le shebang détermine le shell qui exécute le script?

Cela peut être une question idiote, mais je le request encore. Si j'ai déclaré un shebang

#!/bin/bash 

au début de my_shell_script.sh , je dois toujours invoquer ce script en utilisant bash

 [my@comp]$bash my_shell_script.sh 

ou puis-je utiliser par exemple

 [my@comp]$sh my_shell_script.sh 

et mon script détermine le shell en cours d'exécution en utilisant le shebang? Est-ce la même chose avec ksh shell? J'utilise AIX.

    Le shebang #! est une instance lisible par l'homme d'un nombre magique constitué de la string d'octets 0x23 0x21 utilisée par la famille de fonctions exec() pour déterminer si le file à exécuter est un script ou un binary. Quand le shebang est présent, exec() exécutera l'exécutable spécifié après le shebang à la place.

    Notez que cela signifie que si vous appelez un script en spécifiant l'interpréteur sur la command line, comme dans les deux cas donnés dans la question, exec() exécutera l'interpréteur spécifié sur la command line, il ne regardera même pas le script.

    Ainsi, comme vous l'avez noté, si vous voulez que exec() appelle l'interpréteur spécifié sur la ligne shebang, le script doit avoir le bit exécutable défini et ./my_shell_script.sh .

    Le comportement est facile à démontrer avec le script suivant:

     #!/bin/ksh readlink /proc/$$/exe 

    Explication:

    • #!/bin/ksh définit ksh comme l'interpréteur.

    • $$ contient le PID du process en cours.

    • /proc/pid/exe est un lien symbolique vers l'exécutable du process (au less sous Linux, sur AIX, /proc/$$/object/a.out est un lien vers l'exécutable).

    • readlink affichera la valeur du lien symbolique.

    Exemple:

    Note : Je le démontre sur Ubuntu, où le shell par défaut /bin/sh est un lien symbolique au tiret, c'est-à /bin/dash dire /bin/dash et /bin/ksh est un lien symbolique vers /etc/alternatives/ksh , qui est à son tour un lien symbolique à /bin/pdksh .

     $ chmod +x getshell.sh $ ./getshell.sh /bin/pdksh $ bash getshell.sh /bin/bash $ sh getshell.sh /bin/dash 

    Oui. En passant, ce n'est pas une question idiote. Une reference pour ma réponse est ici . Démarrer un script avec #!

    • C'est ce qu'on appelle un shebang ou une ligne "bang".

    • Ce n'est rien d'autre que le path absolu vers l'interpréteur Bash.

    • Il se compose d'un signe numérique et d'un caractère de point d'exclamation (#!), Suivi du path complet de l'interpréteur tel que / bin / bash.

      Tous les scripts sous Linux s'exécutent en utilisant l'interpréteur spécifié sur une première ligne Presque tous les scripts bash commencent souvent par #! / Bin / bash (en supposant que Bash a été installé dans / bin) Cela garantit que Bash sera utilisé pour interpréter le script si elle est exécutée sous un autre shell. Le shebang a été introduit par Dennis Ritchie entre la version 7 Unix et 8 aux laboratoires Bell. Il a ensuite été ajouté à la ligne BSD à Berkeley.

    Ignorer une ligne d'interprète (shebang)

    Si vous ne spécifiez pas de ligne d'interprétation, la valeur par défaut est généralement / bin / sh. Mais, il est recommandé de définir la ligne #! / Bin / bash.

    En fait, si vous le prenez en conséquence, l'exécutable noté dans la ligne shebang, n'est qu'un exécutable. Il est logique d'utiliser un interpréteur de text comme exécutable, mais ce n'est pas nécessaire. Juste pour la clarification et la démonstration, j'ai fait un test plutôt inutile:

     #!/bin/cat useless text more useless text still more useless text 

    Nommé le file test.txt et le bit exectuable chmod u+x test.txt , puis "appelé": ./test.txt . Comme prévu, le contenu du file est généré. Dans ce cas, le chat n'ignore pas la ligne de shebang. Il sort simplement toutes les lignes. Tout interprète utile devrait donc être capable d'ignorer cette ligne de shebang. Pour bash, perl et PHP, c'est simplement une ligne de commentaire. Alors oui, ceux-ci ignorent la ligne de shebang.

    D'après ce que j'ai recueilli, chaque fois qu'un file a un bit exécutable et est invoqué, le kernel parsing l'en-tête du file afin de déterminer comment procéder (pour autant que je sache, vous pouvez append des gestionnaires personnalisés pour les formats de file personnalisés via LKM). Si le file semble être un file text avec un #! combinaison au début, son exécution est envoyée à un autre exécutable (généralement un shell de sortes), dont un path doit être spécifié directement après le dit shebang, sur la même ligne. Le kernel procède alors à l'exécution du shell et transmet le file pour qu'il le gère.

    En bref, peu importe le shell avec lequel vous invoquez le script – le kernel enverra l'exécution dans le cas échéant.