En bash
ou sh
, je suppose que tout ce qui commence par #
est un commentaire .
Mais dans les bash
scripts, nous écrivons:
#!/bin/bash
Et dans les scripts Python, il y a:
#!/bin/python
Est-ce que cela signifie que #
par lui-même est un commentaire alors que #!
n'est pas?
#include
. Là aussi, le#
n'est pas censé être un commentaire.Réponses:
La
#!
ligne est utilisée avant l'exécution du script, puis ignorée lors de son exécution.Vous demandez quelle est la différence entre une ligne shebang et un commentaire ordinaire.
Une ligne commençant par
#!
est tout autant un commentaire qu'une autre ligne commençant par#
. Cela est vrai s'il#!
s'agit de la première ligne du fichier ou ailleurs.#!/bin/sh
a un effet , mais il n'est pas lu par l'interprète lui-même .#
Ce n'est pas un commentaire dans tous les langages de programmation, mais, comme vous le savez, c'est un commentaire dans les shells de style Bourne, notamment (sh
et)bash
(ainsi que la plupart des shells de style non Bourne, par exemplecsh
). C'est aussi un commentaire en Python . Et c'est un commentaire dans une variété de fichiers de configuration qui ne sont pas vraiment des scripts (comme/etc/fstab
).Supposons qu'un script shell commence par
#!/bin/sh
. C'est un commentaire, et l'interprète (le shell) ignore tout ce qui se trouve sur la ligne après le#
personnage.Le but d'une
#!
ligne n'est pas de donner des informations à l'interprète. Le but de la#!
ligne est d'indiquer au système d'exploitation (ou quel que soit le processus qui lance l'interpréteur) ce qu'il doit utiliser comme interprète .Si vous appelez le script en tant que fichier exécutable, par exemple en l'exécutant
./script.sh
, le système consulte la première ligne pour savoir si commence par#!
, suivi de zéro ou plus d'espaces, suivi d'une commande. Si tel est le cas, il exécute cette commande avec le nom du script comme argument. Dans cet exemple, il s'exécute/bin/sh script.sh
(ou techniquement/bin/sh ./script.sh
).Si vous appelez le script en appelant explicitement l'interpréteur, la
#!
ligne n'est jamais consultée. Donc, si vous courezsh script.sh
, la première ligne n'a aucun effet. Siscript2.sh
la première ligne est#!/usr/games/nibbles
lue, l'exécutionsh script2.sh
ne tentera pas d'ouvrir le scriptnibbles
(mais le./script2.sh
fera).Vous remarquerez que dans aucun cas l'extension (
.sh
) du script , si elle en a une, a une incidence sur son exécution. Dans un système de type Unix, cela n’affecte généralement pas la façon dont le script est exécuté. Sur d'autres systèmes, tels que Windows, la#!
ligne shebang peut être entièrement ignorée par le système et l'extension peut déterminer le type d'exécution des scripts. (Cela ne signifie pas que vous devez attribuer des extensions à vos scripts, mais c’est l’une des raisons pour lesquelles elles doivent être correctes.)#!
a été choisi pour servir cet objectif précisément parce que#
commence un commentaire. La#!
ligne est destinée au système, pas à l'interprète, et l'interprète devrait l'ignorer.Shebang Line pour les scripts Bash
Vous avez (à l'origine) dit que vous utilisiez
#!/bin/sh
desbash
scripts. Vous ne devriez le faire que si le script ne nécessite aucunebash
extension - ilsh
doit pouvoir exécuter le script.sh
n'est pas toujours un lien symbolique versbash
. Souvent, y compris sur tous les systèmes Debian et Ubuntu récents et à distance ,sh
un lien symbolique est créédash
.Ligne Shebang pour les scripts Python
Vous avez également indiqué (dans la première version de votre question, avant la modification) que vous démarrez vos scripts Python
#!/bin/sh read by the interpretor
. Si vous voulez dire cela littéralement, alors vous devriez absolument arrêter de le faire. Sihello.py
commence par cette ligne, l'exécution./hello.py
s'exécute:/bin/sh
essaiera d'exécuter un script appeléread
(avecby the interpretor hello.py
comme arguments),read
ne sera (espérons-le) pas trouvé et votre script Python ne sera jamais vu par un interprète Python.Si vous faites cette erreur mais n'avez pas le problème que je décris, vous invoquez probablement vos scripts Python en spécifiant explicitement l'interpréteur (par exemple,
python hello.py
), ce qui a pour effet d'ignorer la première ligne. Lorsque vous distribuez vos scripts à d'autres personnes ou les utilisez longtemps après, il n'est peut-être pas évident que cela leur soit nécessaire. Il est préférable de les réparer maintenant. Ou du moins, supprimez entièrement la première ligne, de sorte que, s’ils ne parviennent pas à s’exécuter avec./
le message d’erreur, cela aura un sens.Pour les scripts Python, si vous savez où se trouve (ou sera) l'interpréteur Python, vous pouvez écrire la
#!
ligne de la même manière:Ou, s'il s'agit d'un script Python 3, vous devez spécifier
python3
, carpython
c'est presque toujours Python 2 :Cependant, le problème est que, même s'il
/bin/sh
est censé exister toujours et/bin/bash
presque toujours sur les systèmesbash
livrés avec le système d'exploitation, Python peut exister à divers endroits.Par conséquent, de nombreux programmeurs Python utilisent ceci à la place:
(Ou
#!/usr/bin/env python3
pour Python 3.)Cela fait que le script se base sur le fait d'
env
être au "bon endroit" au lieu de se fierpython
au bon endroit. C'est une bonne chose car:env
est presque toujours situé dans/usr/bin
.python
doit exécuter votre script est celui qui apparaît en premier dans le répertoirePATH
. En commençanthello.py
par#!/usr/bin/env python
make./hello.py
run/usr/bin/env python hello.py
, ce qui est (pratiquement) équivalent à courirpython hello.py
.La raison pour laquelle vous ne pouvez pas utiliser
#!python
est que:/
).python
dans le répertoire en cours . La recherche du chemin lorsque la commande ne contient pas de barre oblique est un comportement spécifique du shell.Parfois, un script Python ou autre script qui n'est pas un script shell aura une ligne shebang commençant par
#!/bin/sh ...
où se...
trouve un autre code. C'est parfois correct, car il existe des moyens d'appeler le shell (sh
) compatible Bourne avec des arguments pour le faire appeler un interpréteur Python. (Un des arguments le contiendra probablementpython
.) Cependant, dans la plupart des cas, il#!/usr/bin/env python
est plus simple, plus élégant et plus susceptible de fonctionner comme vous le souhaitez.Lignes Shebang dans d'autres langues
De nombreux langages de programmation et de script, ainsi que d'autres formats de fichiers, utilisent
#
comme commentaires. Pour n'importe lequel d'entre eux, un fichier dans la langue peut être exécuté par un programme qui le prend comme argument en spécifiant le programme sur la première ligne suivante#!
.Dans certains langages de programmation, ce
#
n’est normalement pas un commentaire, mais dans un cas particulier, la première ligne est ignorée si elle commence par#!
. Cela facilite l'utilisation de la#!
syntaxe même si, par#
ailleurs, une ligne n'est pas un commentaire.Lignes Shebang pour les fichiers qui ne s'exécutent pas en tant que scripts
Bien que ce soit moins intuitif, tout fichier dont le format de fichier peut accueillir une première ligne commençant par
#!
suivi du chemin complet d'un exécutable peut avoir une ligne shebang. Si vous faites cela, et que le fichier est marqué comme exécutable, vous pouvez l'exécuter comme un programme ... et ainsi l'ouvrir comme un document.Certaines applications utilisent ce comportement intentionnellement. Par exemple, dans VMware, les
.vmx
fichiers définissent des machines virtuelles. Vous pouvez "exécuter" une machine virtuelle comme s'il s'agissait d'un script, car ces fichiers sont marqués comme étant exécutables et comportent une ligne shebang, ce qui les ouvre dans un utilitaire VMware.Lignes Shebang pour les fichiers qui ne s'exécutent pas comme des scripts mais agissent comme des scripts de toute façon
rm
supprime les fichiers. Ce n'est pas un langage de script. Cependant, un fichier qui commence#!/bin/rm
et qui est marqué comme exécutable peut être exécuté. Lorsque vous l'exécutez, ilrm
est appelé, ce qui le supprime.Ceci est souvent conceptualisé comme "le fichier se supprime lui-même". Mais le fichier ne fonctionne pas vraiment du tout. Cela ressemble plus à la situation décrite ci-dessus pour les
.vmx
fichiers.Néanmoins, comme la
#!
ligne facilite l'exécution d'une commande simple (y compris les arguments de ligne de commande), vous pouvez effectuer certains scripts de cette manière. Comme exemple simple d'un "script" plus sophistiqué que#!/bin/rm
, considérons:Cela prend les entrées de l'utilisateur de manière interactive, les renvoie ligne par ligne à l'utilisateur et les ajoute à la fin du fichier "script".
Utile? Pas très. Conceptuellement intéressant? Totalement! Oui. (Quelque peu.)
Concepts de programmation / script similaires (juste pour le plaisir)
Scripts / programmes utilisant plusieurs langues à la fois , par exemple, pour simuler la fonctionnalité hashbang dans des systèmes d’exploitation qui n’en étaient pas dotés .
(Ces programmes sont appelés polyglottes , mais ceci ne doit pas être confondu avec l'autre sens du terme polyglotte dans le développement logiciel , un programme / projet dans lequel différentes parties sont écrites dans différentes langues.)
Métacommandes dans QBasic / QuickBASIC, qui signalaient au compilateur (pour le code compilé) des options pour la génération de code, mais faisaient partie de commentaires et étaient donc ignorées lors de la compilation / interprétation.
la source
-x
indicateur Pythons ?-x
"ignorer la première ligne ..." la 2ème ligne est numérotée1
au lieu de2
, la 3ème ligne2
au lieu de3
, etc. C'est pourquoi vous ne devriez pas utiliser ce drapeau. ;)-x
est destiné aux scripts sur des systèmes d’exploitation non-Unix-semblables à la syntaxe shebang-like ne commençant pas par#
(donc pas un commentaire de Python).perl script.pl
rapport./script.pl
) , puis l'interprète va lire la ligne de tralala pour analyser des drapeaux tels que-w
. Il n'est toutefois pas recommandé de s'appuyer sur cette fonctionnalité.Un shebang est la séquence de caractères constituée du signe de nombre de caractères et du point d'exclamation (par exemple, "#!") Lorsqu'il apparaît comme les deux premiers caractères de la première ligne d'un script.
Sous les systèmes d'exploitation * nix, lorsqu'un script commençant par un shebang est exécuté, le programme de chargement analyse le reste de la ligne initiale du script sous forme de directive interpréteur; le programme interpréteur spécifié est exécuté à la place, en lui transmettant en tant qu'argument le chemin initialement utilisé lors de la tentative d'exécution du script. Par exemple, si un script est nommé avec le chemin "chemin / vers / votre script", il commence par la ligne suivante:
ensuite, le chargeur de programmes doit exécuter le programme "/ bin / sh" à la place, par exemple, le shell Bourne ou un shell compatible, en transmettant "path / to / votre-script" comme premier argument.
En conséquence, un script est nommé avec le chemin "chemin / vers / python-script" et commence par la ligne suivante:
ensuite, le programme chargé est invité à exécuter le programme "/ bin / python" à la place, par exemple, d'un interpréteur Python, en passant "chemin / vers / python-script" comme premier argument.
En bref, "#" commentera une ligne tandis que la séquence de caractères "#!" apparaissant comme les deux premiers caractères de la première ligne d’un script a la signification décrite ci-dessus.
Pour plus de détails, voir Pourquoi certains scripts commencent par #! ...?
Source: Certaines sections de cette réponse proviennent (avec de légères modifications) de Shebang (Unix) sur Wikipedia anglais (par des contributeurs de Wikipédia ). Cet article est sous licence CC-BY-SA 3.0 , comme le contenu de l'utilisateur, ici sur AU. Cette dérivation est donc autorisée avec attribution.
la source
#!
est appelé leshebang
quand il apparaît comme les deux premiers caractères de la première ligne d'un script. Il est utilisé dans les scripts pour indiquer un interpréteur à exécuter. Leshebang
est pour le système d'exploitation (noyau), pas pour le shell; donc cela ne sera pas interprété comme un commentaire.Courtesy: http://en.wikipedia.org/wiki/Shebang_%28Unix%29
Informations détaillées: http://wiki.bash-hackers.org/scripting/basics#the_shebang
la source
Non, il est uniquement utilisé par l'
exec
appel système du noyau Linux et traité comme un commentaire par l'interpréteur.Quand vous faites sur bash:
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#L25Il 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:et cela fonctionne pour tout langage de script utilisant
#
un caractère de commentaire.Et oui, vous pouvez faire une boucle infinie avec:
Bash reconnaît l'erreur:
#!
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’octets7f 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:sortie:
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 soit mentionné dans les sections de justification, et sous la forme "si les scripts exécutables sont pris en charge par le système se produire".
la source