La réponse ci-dessous indique qu'il ne s'agit que d'une ligne de commentaire. Ce n'est pas toujours le cas. J'ai un "Bonjour, monde!" Script CGI (.py) qui ne fonctionnera et affichera la page Web qu'en #!/usr/bin/env pythonhaut.
Ils peuvent courir, mais pas dans l'environnement prévu
Nicholas Hamilton
18
J'ai visité ce poste tant de fois en 7 ans parce que j'oublie parfois l'env hashbang. Copier les pâtes :)
BugHunterUK
Réponses:
1084
Si vous avez plusieurs versions de Python installées, vous vous /usr/bin/envassurerez que l'interpréteur utilisé est le premier sur votre environnement $PATH. L'alternative serait de coder en dur quelque chose comme #!/usr/bin/python; c'est ok, mais moins flexible.
Sous Unix, un fichier exécutable destiné à être interprété peut indiquer quel interpréteur utiliser en ayant un #!au début de la première ligne, suivi de l'interpréteur (et de tous les indicateurs dont il peut avoir besoin).
Si vous parlez d'autres plates-formes, bien sûr, cette règle ne s'applique pas (mais cette "ligne shebang" ne fait aucun mal, et vous aidera si vous copiez jamais ce script sur une plate-forme avec une base Unix, telle que Linux, Mac , etc).
Juste pour ajouter: cela s'applique lorsque vous l'exécutez sous Unix en le rendant exécutable ( chmod +x myscript.py) puis en l'exécutant directement:, ./myscript.pyplutôt que simplement python myscript.py.
Craig McQueen
28
l'utilisation envdonne une flexibilité maximale dans la mesure où l'utilisateur peut sélectionner l'interpréteur à utiliser en changeant le CHEMIN. Souvent, cette flexibilité n'est cependant pas requise et l'inconvénient est que Linux par exemple ne peut pas utiliser le nom du script pour le nom du processus dans pset revient à "python". Lors du packaging d'applications python pour des distributions par exemple, je vous déconseille de les utiliser env.
Un avertissement important, la valeur de retour d'env expire finalement. Ce qui est peu susceptible de vous affecter si vous exécutez des processus de courte durée. Cependant, j'ai eu des processus qui meurent avec le message /usr/bin/env: Key has expiredaprès plusieurs heures.
malaverdiere
4
@malaverdiere pouvez-vous créer un lien vers des ressources expliquant ce comportement d'expiration? Je ne les trouve pas.
En informatique, un shebang (également appelé hashbang, hashpling, pound bang ou crunchbang) fait référence aux caractères "#!" lorsqu'ils sont les deux premiers caractères d'une directive interpréteur comme première ligne d'un fichier texte. Dans un système d'exploitation de type Unix, le programme de chargement prend la présence de ces deux caractères comme une indication que le fichier est un script et essaie d'exécuter ce script à l'aide de l'interpréteur spécifié par le reste de la première ligne du fichier.
Même sous Windows, où la ligne shebang ne détermine pas l'interpréteur à exécuter, vous pouvez transmettre des options à l'interpréteur en les spécifiant sur la ligne shebang. Je trouve utile de conserver une ligne générique de shebang dans des scripts uniques (tels que ceux que j'écris lorsque je réponds à des questions sur SO), afin de pouvoir les tester rapidement sur Windows et ArchLinux .
L' utilitaire env vous permet d'appeler une commande sur le chemin:
Le premier argument restant spécifie le nom du programme à invoquer; il est recherché selon la PATHvariable d'environnement. Tous les arguments restants sont passés comme arguments à ce programme.
Facile à trouver avec Google - si l'on connaît les mots-clés (la "ligne shebang" est essentielle).
Arafangion
14
En fait, cette explication est plus claire que les autres références que j'ai vérifiées avec Google. Il est toujours plus agréable d'obtenir une explication d'un paragraphe ciblant la question, plutôt que de lire un manuel complet traitant de chaque utilisation potentielle.
@ulidtko: Moteur de recherche intéressant, pensez à écrire une réponse pour que la question de john garcias ait une meilleure réponse.
Arafangion
1
"Même sous Windows, où la ligne shebang ne détermine pas l'interpréteur à exécuter, vous pouvez transmettre des options à l'interpréteur en les spécifiant sur la ligne shebang." C'est tout simplement faux; si une telle chose se produit, c'est parce que l'interpréteur lui-même traite la ligne shebang. Si l'interprète n'a pas de reconnaissance spéciale pour les lignes de shebang, alors rien de tel ne se produit. Windows ne fait rien avec les lignes de shebang. "Ce que vous décrivez peut-être dans ce cas est le lanceur python: python.org/dev/peps/pep-0397 .
Kaz
154
Développant un peu les autres réponses, voici un petit exemple de la façon dont vos scripts de ligne de commande peuvent avoir des ennuis en utilisant /usr/bin/envprudemment les lignes de shebang:
Une façon de se prémunir contre ce type de problème consiste à utiliser les noms de commande python versionnés qui sont généralement installés avec la plupart des Pythons:
Si vous avez juste besoin de faire la distinction entre Python 2.x et Python 3.x, les versions récentes de Python 3 fournissent également un python3nom:
Différence entre local et global. Si le which pythonrendement /usr/bin/python, un chemin de répertoire local pourrait être codé en dur: #!/usr/bin/python. Mais c'est moins flexible que celui #!/usr/bin/env pythonqui a une application globale.
noobninja
85
Afin d'exécuter le script python, nous devons dire au shell trois choses:
Que le fichier est un script
Quel interprète nous voulons exécuter le script
Le parcours dudit interprète
Le shebang #!accomplit (1.). Le shebang commence par un #car le #personnage est un marqueur de commentaire dans de nombreux langages de script. Le contenu de la ligne shebang est donc automatiquement ignoré par l'interprète.
La envcommande accomplit (2.) et (3.). Pour citer "grawity"
Une utilisation courante de la envcommande est de lancer des interprètes, en utilisant le fait que env recherchera $ PATH pour la commande qu'on lui demande de lancer. Étant donné que la ligne shebang nécessite la spécification d'un chemin absolu et que l'emplacement des divers interprètes (perl, bash, python) peut varier considérablement, il est courant d'utiliser:
#!/usr/bin/env perl au lieu d'essayer de deviner s'il s'agit de / bin / perl, / usr / bin / perl, / usr / local / bin / perl, / usr / local / pkg / perl, / fileserver / usr / bin / perl ou / home / MrDaniel / usr / bin / perl sur le système de l'utilisateur ...
D'un autre côté, env est presque toujours dans / usr / bin / env. (Sauf dans les cas où ce n'est pas le cas; certains systèmes peuvent utiliser / bin / env, mais c'est une occasion assez rare et ne se produit que sur des systèmes non Linux.)
Vous n'avez pas du tout besoin de cette ligne. Le système appellera python puis l'interpréteur python exécutera votre script.
Mais si vous avez l'intention d'utiliser: $./myscript.py
En l'appelant directement comme un programme normal ou un script bash, vous devez écrire cette ligne pour spécifier au système quel programme utiliser pour l'exécuter, (et aussi le rendre exécutable avec chmod 755)
Il lit les tout premiers octets du fichier et les compare à #!.
Si la comparaison est vraie, le reste de la ligne est analysé par le noyau Linux, ce qui en fait un autre exec appel avec chemin /usr/bin/env pythonet fichier actuel comme premier argument:
/usr/bin/env python /path/to/script.py
et cela fonctionne pour tout langage de script qui utilise #comme 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 être lisible par l'homme, mais ce n'est pas obligatoire.
Si le fichier a commencé avec différents octets, l' execappel système utiliserait un gestionnaire différent. 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 les octets 7f 45 4c 46(qui se trouvent également être humains) lisible pour .ELF). Confirmons qu'en lisant les 4 premiers octets de /bin/ls, qui est un exécutable ELF:
Je ne pense pas que POSIX spécifie des shebangs cependant: https://unix.stackexchange.com/a/346214/32558 , bien qu'il mentionne dans les sections sur la justification et sous la forme "si les scripts exécutables sont pris en charge par le système, quelque chose peut se produire". macOS et FreeBSD semblent également l'implémenter.
PATH motivation de recherche
Probablement, une grande motivation pour l'existence de shebangs est le fait que sous Linux, nous voulons souvent exécuter des commandes à partir PATHde:
basename-of-command
au lieu de:
/full/path/to/basename-of-command
Mais alors, sans le mécanisme shebang, comment Linux saurait-il lancer chaque type de fichier?
Codage en dur de l'extension dans les commandes:
basename-of-command.py
ou implémentant la recherche PATH sur chaque interprète:
python basename-of-command
serait une possibilité, mais cela a le problème majeur que tout se casse si nous décidons de refactoriser la commande dans une autre langue.
Techniquement, en Python, ce n'est qu'une ligne de commentaire.
Cette ligne n'est utilisée que si vous exécutez le script py à partir du shell (à partir de la ligne de commande). Ceci est connu comme le " Shebang !" , et il est utilisé dans diverses situations, pas seulement avec des scripts Python.
Ici, il demande au shell de démarrer une version spécifique de Python (pour prendre soin du reste du fichier.
Le shebang est un concept Unix. Il peut être utile de mentionner qu'il fonctionne également sur Windows si vous avez installé le lanceur Pythonpy.exe . Cela fait partie d'une installation Python standard.
florisla
38
La principale raison pour cela est de rendre le script portable dans les environnements de système d'exploitation.
Par exemple sous mingw, les scripts python utilisent:
#!/c/python3k/python
et sous distribution GNU / Linux c'est soit:
#!/usr/local/bin/python
ou
#!/usr/bin/python
et sous le meilleur système commercial Unix sw / hw de tous (OS / X), c'est:
#!/Applications/MacPython 2.5/python
ou sur FreeBSD:
#!/usr/local/bin/python
Cependant, toutes ces différences peuvent rendre le script portable à tous en utilisant:
Sous MacOSX, c'est aussi /usr/bin/python. Sous Linux, le Python installé par le système l'est aussi presque certainement /usr/bin/python(je n'ai jamais rien vu d'autre et cela n'aurait aucun sens). Notez qu'il peut y avoir des systèmes qui n'en ont pas /usr/bin/env.
Albert
1
Si vous êtes sur OSX et utilisez Homebrew et suivez leurs instructions d'installation par défaut, ce sera sous #! / Usr / local / bin / python
Will
@ Jean-PaulCalderone: Voir la réponse de saaj ci-dessous.
pydsigner
Mise à jour pour l'année 2018: Bare pythonn'est pas si portable, c'est l'interpréteur Python par défaut de la distribution. Arch Linux utilise par défaut Python 3 depuis longtemps et les distributions peuvent y penser aussi parce que Python 2 n'est pris en charge que jusqu'en 2020.
mati865
22
Il est probablement logique de souligner une chose que la plupart ont manqué, ce qui peut empêcher une compréhension immédiate. Lorsque vous tapez pythonterminal, vous ne fournissez normalement pas de chemin complet. Au lieu de cela, l'exécutable est recherché dans PATHla variable d'environnement. À son tour, lorsque vous souhaitez exécuter un programme Python directement /path/to/app.py, vous devez indiquer au shell quel interpréteur utiliser (via le hashbang , ce que les autres contributeurs expliquent ci-dessus).
Hashbang attend le chemin complet vers un interprète. Ainsi, pour exécuter votre programme Python directement, vous devez fournir un chemin complet vers le binaire Python qui varie considérablement, en particulier compte tenu de l'utilisation de virtualenv . Pour aborder la portabilité, l'astuce avec /usr/bin/envest utilisée. Ce dernier est à l'origine destiné à modifier l'environnement en place et à exécuter une commande dans celui-ci. Lorsqu'aucune modification n'est fournie, il exécute la commande dans l'environnement actuel, ce qui entraîne effectivement la mêmePATH recherche qui fait l'affaire.
Il spécifie simplement quel interprète vous souhaitez utiliser. Pour comprendre cela, créez un fichier via le terminal en faisant touch test.py, puis tapez dans ce fichier ce qui suit:
#!/usr/bin/env python3print"test"
et faites chmod +x test.pypour rendre votre script exécutable. Après cela, ./test.pyvous devriez obtenir une erreur indiquant:
File"./test.py", line 2print"test"^SyntaxError:Missing parentheses in call to 'print'
car python3 ne prend pas en charge l'opérateur d'impression.
Maintenant, allez-y et changez la première ligne de votre code en:
#!/usr/bin/env python2
et cela fonctionnera, en imprimant testsur stdout, car python2 prend en charge l'opérateur d'impression. Ainsi, vous avez maintenant appris à basculer entre les interpréteurs de script.
Il me semble que les fichiers fonctionnent de la même manière sans cette ligne.
Si oui, alors vous exécutez peut-être le programme Python sous Windows? Windows n'utilise pas cette ligne - à la place, il utilise l'extension de nom de fichier pour exécuter le programme associé à l'extension de fichier.
Cependant en 2011, un "lanceur Python" a été développé qui imite (dans une certaine mesure) ce comportement Linux pour Windows. Ceci se limite uniquement au choix de l'interpréteur Python à exécuter - par exemple pour sélectionner entre Python 2 et Python 3 sur un système où les deux sont installés. Le lanceur est éventuellement installé comme py.exepar l'installation Python et peut être associé à des .pyfichiers afin que le lanceur vérifie cette ligne et lance à son tour la version d'interpréteur Python spécifiée.
Il pourrait également utiliser $ python myscript.py.
Sinan Ünür
J'ai fait l'erreur de ne pas avoir la ligne et d'utiliser python script.py, et un jour je l'ai fait ./myscript.py et tout a cessé de fonctionner, puis je me suis rendu compte que le système regarde le fichier comme un script shell au lieu d'un script python.
Guagua
8
Cela signifie plus d'informations historiques qu'une réponse «réelle».
Rappelez - vous que dans la journée vous eu beaucoup de unix comme les systèmes d' exploitation dont les concepteurs avaient tous leur propre idée de l' endroit où mettre des choses, et parfois ne comprennent pas Python, Perl, Bash, ou beaucoup d'autres GNU / Open Source substance du tout .
Cela était même vrai pour différentes distributions Linux. Sous Linux - pré-FHS [1] - vous pourriez avoir python dans / usr / bin / ou / usr / local / bin /. Ou il n'a peut-être pas été installé, alors vous avez construit le vôtre et le mettez dans ~ / bin
Solaris a été le pire sur lequel j'ai jamais travaillé, en partie lors de la transition de Berkeley Unix au système V. Vous pouvez vous retrouver avec des choses dans / usr /, / usr / local /, / usr / ucb, / opt / etc. pour certains très longs chemins. J'ai des souvenirs de ce que Sunfreeware.com a installé chaque paquet dans son propre répertoire, mais je ne me souviens pas s'il a lié les binaires dans / usr / bin ou non.
Oh, et parfois / usr / bin était sur un serveur NFS [2].
L' envutilitaire a donc été développé pour contourner ce problème.
Ensuite, vous pouviez écrire #!/bin/env interpreteret tant que le chemin était correct, les choses avaient une chance raisonnable de courir. Bien sûr, raisonnable signifiait (pour Python et Perl) que vous aviez également défini les variables d'environnement appropriées. Pour bash / ksh / zsh, cela a juste fonctionné.
C'était important parce que les gens passaient autour des scripts shell (comme perl et python) et si vous aviez codé en dur / usr / bin / python sur votre poste de travail Red Hat Linux, ça allait mal se passer sur un SGI ... enfin, non , Je pense que IRIX a mis le python au bon endroit. Mais sur une station Sparc, il pourrait ne pas fonctionner du tout.
Ma station Sparc me manque. Mais pas beaucoup. Ok, maintenant tu me fais traîner sur E-Bay. Bastages.
Si vous exécutez votre script dans un environnement virtuel, par exemple venv, l'exécution which pythonen travaillant sur venvaffichera le chemin vers l'interpréteur Python:
~/Envs/venv/bin/python
Notez que le nom de l'environnement virtuel est incorporé dans le chemin d'accès à l'interpréteur Python. Par conséquent, le codage en dur de ce chemin dans votre script entraînera deux problèmes:
Si vous téléchargez le script dans un référentiel, vous forcez les autres utilisateurs à avoir le même nom d'environnement virtuel . C'est s'ils identifient le problème en premier.
Vous ne pourrez pas exécuter le script sur plusieurs environnements virtuels même si vous disposiez de tous les packages requis dans d'autres environnements virtuels.
Par conséquent, pour ajouter à la réponse de Jonathan , le shebang idéal est #!/usr/bin/env python, non seulement pour la portabilité entre les systèmes d'exploitation, mais aussi pour la portabilité entre les environnements virtuels!
Compte tenu des problèmes de portabilité entre python2et python3, vous devez toujours spécifier l'une ou l'autre version, sauf si votre programme est compatible avec les deux.
Certaines distributions expédiez un pythonlien symbolique à python3un certain temps maintenant - ne comptez pas sur l' pythonêtrepython2 .
Afin de tolérer les différences entre plates-formes, tout nouveau code qui doit appeler l'interpréteur Python ne doit pas spécifier python, mais doit plutôt spécifier python2 ou python3 (ou les versions plus spécifiques python2.x et python3.x; voir les notes de migration ) . Cette distinction doit être faite dans les shebangs, lors de l'appel à partir d'un script shell, lors de l'appel via l'appel system (), ou lors de l'appel dans tout autre contexte.
Il vous permet de sélectionner l'exécutable que vous souhaitez utiliser; ce qui est très pratique si vous avez peut-être plusieurs installations python et différents modules dans chacun et que vous souhaitez choisir. par exemple
#!/bin/sh## Choose the python we need. Explanation:# a) '''\' translates to \ in shell, and starts a python multi-line string# b) "" strings are treated as string concat by python, shell ignores them# c) "true" command ignores its arguments# c) exit before the ending ''' so the shell reads no further# d) reset set docstrings to ignore the multiline comment code#"true"'''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3
if [ -x $PREFERRED_PYTHON ]; then
echo Using preferred python $ALTERNATIVE_PYTHON
exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
echo Using alternative python $ALTERNATIVE_PYTHON
exec $ALTERNATIVE_PYTHON "$0" "$@"
else
echo Using fallback python $FALLBACK_PYTHON
exec python3 "$0" "$@"
fi
exit 127
'''
__doc__ ="""What this file does"""print(__doc__)import platform
print(platform.python_version())
#!/usr/bin/env python
haut.Réponses:
Si vous avez plusieurs versions de Python installées, vous vous
/usr/bin/env
assurerez que l'interpréteur utilisé est le premier sur votre environnement$PATH
. L'alternative serait de coder en dur quelque chose comme#!/usr/bin/python
; c'est ok, mais moins flexible.Sous Unix, un fichier exécutable destiné à être interprété peut indiquer quel interpréteur utiliser en ayant un
#!
au début de la première ligne, suivi de l'interpréteur (et de tous les indicateurs dont il peut avoir besoin).Si vous parlez d'autres plates-formes, bien sûr, cette règle ne s'applique pas (mais cette "ligne shebang" ne fait aucun mal, et vous aidera si vous copiez jamais ce script sur une plate-forme avec une base Unix, telle que Linux, Mac , etc).
la source
chmod +x myscript.py
) puis en l'exécutant directement:,./myscript.py
plutôt que simplementpython myscript.py
.env
donne une flexibilité maximale dans la mesure où l'utilisateur peut sélectionner l'interpréteur à utiliser en changeant le CHEMIN. Souvent, cette flexibilité n'est cependant pas requise et l'inconvénient est que Linux par exemple ne peut pas utiliser le nom du script pour le nom du processus dansps
et revient à "python". Lors du packaging d'applications python pour des distributions par exemple, je vous déconseille de les utiliserenv
.py
le lanceur peut utiliser la ligne shebang sous Windows. Il est inclus dans Python 3.3 ou il peut être installé indépendamment ./usr/bin/env: Key has expired
après plusieurs heures.C'est ce qu'on appelle la ligne shebang . Comme l' explique l'entrée Wikipedia :
Voir aussi l' entrée FAQ Unix .
Même sous Windows, où la ligne shebang ne détermine pas l'interpréteur à exécuter, vous pouvez transmettre des options à l'interpréteur en les spécifiant sur la ligne shebang. Je trouve utile de conserver une ligne générique de shebang dans des scripts uniques (tels que ceux que j'écris lorsque je réponds à des questions sur SO), afin de pouvoir les tester rapidement sur Windows et ArchLinux .
L' utilitaire env vous permet d'appeler une commande sur le chemin:
la source
Développant un peu les autres réponses, voici un petit exemple de la façon dont vos scripts de ligne de commande peuvent avoir des ennuis en utilisant
/usr/bin/env
prudemment les lignes de shebang:Le module json n'existe pas dans Python 2.5.
Une façon de se prémunir contre ce type de problème consiste à utiliser les noms de commande python versionnés qui sont généralement installés avec la plupart des Pythons:
Si vous avez juste besoin de faire la distinction entre Python 2.x et Python 3.x, les versions récentes de Python 3 fournissent également un
python3
nom:la source
which python
rendement/usr/bin/python
, un chemin de répertoire local pourrait être codé en dur:#!/usr/bin/python
. Mais c'est moins flexible que celui#!/usr/bin/env python
qui a une application globale.Afin d'exécuter le script python, nous devons dire au shell trois choses:
Le shebang
#!
accomplit (1.). Le shebang commence par un#
car le#
personnage est un marqueur de commentaire dans de nombreux langages de script. Le contenu de la ligne shebang est donc automatiquement ignoré par l'interprète.La
env
commande accomplit (2.) et (3.). Pour citer "grawity"la source
Votre question est peut-être en ce sens:
Si vous souhaitez utiliser:
$python myscript.py
Vous n'avez pas du tout besoin de cette ligne. Le système appellera python puis l'interpréteur python exécutera votre script.
Mais si vous avez l'intention d'utiliser:
$./myscript.py
En l'appelant directement comme un programme normal ou un script bash, vous devez écrire cette ligne pour spécifier au système quel programme utiliser pour l'exécuter, (et aussi le rendre exécutable avec
chmod 755
)la source
L'
exec
appel système du noyau Linux comprend#!
nativement shebangs ( )Quand tu fais 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, le reste de la ligne est analysé par le noyau Linux, ce qui en fait un autre
exec
appel avec chemin/usr/bin/env python
et fichier actuel comme premier argument:et cela fonctionne pour tout langage de script qui utilise
#
comme caractère de commentaire.Et oui, vous pouvez faire une boucle infinie avec:
Bash reconnaît l'erreur:
#!
se trouve être lisible par l'homme, mais ce n'est pas obligatoire.Si le fichier a commencé avec différents octets, l'
exec
appel système utiliserait un gestionnaire différent. 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 les octets7f 45 4c 46
(qui se trouvent également être humains) lisible pour.ELF
). Confirmons qu'en lisant les 4 premiers octets de/bin/ls
, qui est un exécutable ELF:production:
Ainsi, lorsque le noyau voit ces octets, il prend le fichier ELF, le place correctement en mémoire et démarre un nouveau processus avec lui. Voir aussi: Comment le noyau obtient-il un fichier binaire exécutable sous Linux?
Enfin, vous pouvez ajouter vos propres gestionnaires de 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 .Je ne pense pas que POSIX spécifie des shebangs cependant: https://unix.stackexchange.com/a/346214/32558 , bien qu'il mentionne dans les sections sur la justification et sous la forme "si les scripts exécutables sont pris en charge par le système, quelque chose peut se produire". macOS et FreeBSD semblent également l'implémenter.
PATH
motivation de rechercheProbablement, une grande motivation pour l'existence de shebangs est le fait que sous Linux, nous voulons souvent exécuter des commandes à partir
PATH
de:au lieu de:
Mais alors, sans le mécanisme shebang, comment Linux saurait-il lancer chaque type de fichier?
Codage en dur de l'extension dans les commandes:
ou implémentant la recherche PATH sur chaque interprète:
serait une possibilité, mais cela a le problème majeur que tout se casse si nous décidons de refactoriser la commande dans une autre langue.
Shebangs résout magnifiquement ce problème.
la source
Techniquement, en Python, ce n'est qu'une ligne de commentaire.
Cette ligne n'est utilisée que si vous exécutez le script py à partir du shell (à partir de la ligne de commande). Ceci est connu comme le " Shebang !" , et il est utilisé dans diverses situations, pas seulement avec des scripts Python.
Ici, il demande au shell de démarrer une version spécifique de Python (pour prendre soin du reste du fichier.
la source
py.exe
. Cela fait partie d'une installation Python standard.La principale raison pour cela est de rendre le script portable dans les environnements de système d'exploitation.
Par exemple sous mingw, les scripts python utilisent:
et sous distribution GNU / Linux c'est soit:
ou
et sous le meilleur système commercial Unix sw / hw de tous (OS / X), c'est:
ou sur FreeBSD:
Cependant, toutes ces différences peuvent rendre le script portable à tous en utilisant:
la source
/usr/bin/python
. Sous Linux, le Python installé par le système l'est aussi presque certainement/usr/bin/python
(je n'ai jamais rien vu d'autre et cela n'aurait aucun sens). Notez qu'il peut y avoir des systèmes qui n'en ont pas/usr/bin/env
.python
n'est pas si portable, c'est l'interpréteur Python par défaut de la distribution. Arch Linux utilise par défaut Python 3 depuis longtemps et les distributions peuvent y penser aussi parce que Python 2 n'est pris en charge que jusqu'en 2020.Il est probablement logique de souligner une chose que la plupart ont manqué, ce qui peut empêcher une compréhension immédiate. Lorsque vous tapez
python
terminal, vous ne fournissez normalement pas de chemin complet. Au lieu de cela, l'exécutable est recherché dansPATH
la variable d'environnement. À son tour, lorsque vous souhaitez exécuter un programme Python directement/path/to/app.py
, vous devez indiquer au shell quel interpréteur utiliser (via le hashbang , ce que les autres contributeurs expliquent ci-dessus).Hashbang attend le chemin complet vers un interprète. Ainsi, pour exécuter votre programme Python directement, vous devez fournir un chemin complet vers le binaire Python qui varie considérablement, en particulier compte tenu de l'utilisation de virtualenv . Pour aborder la portabilité, l'astuce avec
/usr/bin/env
est utilisée. Ce dernier est à l'origine destiné à modifier l'environnement en place et à exécuter une commande dans celui-ci. Lorsqu'aucune modification n'est fournie, il exécute la commande dans l'environnement actuel, ce qui entraîne effectivement la mêmePATH
recherche qui fait l'affaire.Source depuis unix stackexchange
la source
Il s'agit d'une convention shell qui indique au shell quel programme peut exécuter le script.
résout un chemin vers le binaire Python.
la source
Il est recommandé, proposé dans la documentation:
depuis http://docs.python.org/py3k/tutorial/interpreter.html#executable-python-scripts
la source
Vous pouvez essayer ce problème en utilisant virtualenv
Voici test.py
Créer des environnements virtuels
activer chaque environnement puis vérifier les différences
la source
Il spécifie simplement quel interprète vous souhaitez utiliser. Pour comprendre cela, créez un fichier via le terminal en faisant
touch test.py
, puis tapez dans ce fichier ce qui suit:et faites
chmod +x test.py
pour rendre votre script exécutable. Après cela,./test.py
vous devriez obtenir une erreur indiquant:car python3 ne prend pas en charge l'opérateur d'impression.
Maintenant, allez-y et changez la première ligne de votre code en:
et cela fonctionnera, en imprimant
test
sur stdout, car python2 prend en charge l'opérateur d'impression. Ainsi, vous avez maintenant appris à basculer entre les interpréteurs de script.la source
Si oui, alors vous exécutez peut-être le programme Python sous Windows? Windows n'utilise pas cette ligne - à la place, il utilise l'extension de nom de fichier pour exécuter le programme associé à l'extension de fichier.
Cependant en 2011, un "lanceur Python" a été développé qui imite (dans une certaine mesure) ce comportement Linux pour Windows. Ceci se limite uniquement au choix de l'interpréteur Python à exécuter - par exemple pour sélectionner entre Python 2 et Python 3 sur un système où les deux sont installés. Le lanceur est éventuellement installé comme
py.exe
par l'installation Python et peut être associé à des.py
fichiers afin que le lanceur vérifie cette ligne et lance à son tour la version d'interpréteur Python spécifiée.la source
$ python myscript.py
.Cela signifie plus d'informations historiques qu'une réponse «réelle».
Rappelez - vous que dans la journée vous eu beaucoup de unix comme les systèmes d' exploitation dont les concepteurs avaient tous leur propre idée de l' endroit où mettre des choses, et parfois ne comprennent pas Python, Perl, Bash, ou beaucoup d'autres GNU / Open Source substance du tout .
Cela était même vrai pour différentes distributions Linux. Sous Linux - pré-FHS [1] - vous pourriez avoir python dans / usr / bin / ou / usr / local / bin /. Ou il n'a peut-être pas été installé, alors vous avez construit le vôtre et le mettez dans ~ / bin
Solaris a été le pire sur lequel j'ai jamais travaillé, en partie lors de la transition de Berkeley Unix au système V. Vous pouvez vous retrouver avec des choses dans / usr /, / usr / local /, / usr / ucb, / opt / etc. pour certains très longs chemins. J'ai des souvenirs de ce que Sunfreeware.com a installé chaque paquet dans son propre répertoire, mais je ne me souviens pas s'il a lié les binaires dans / usr / bin ou non.
Oh, et parfois / usr / bin était sur un serveur NFS [2].
L'
env
utilitaire a donc été développé pour contourner ce problème.Ensuite, vous pouviez écrire
#!/bin/env interpreter
et tant que le chemin était correct, les choses avaient une chance raisonnable de courir. Bien sûr, raisonnable signifiait (pour Python et Perl) que vous aviez également défini les variables d'environnement appropriées. Pour bash / ksh / zsh, cela a juste fonctionné.C'était important parce que les gens passaient autour des scripts shell (comme perl et python) et si vous aviez codé en dur / usr / bin / python sur votre poste de travail Red Hat Linux, ça allait mal se passer sur un SGI ... enfin, non , Je pense que IRIX a mis le python au bon endroit. Mais sur une station Sparc, il pourrait ne pas fonctionner du tout.
Ma station Sparc me manque. Mais pas beaucoup. Ok, maintenant tu me fais traîner sur E-Bay. Bastages.
[1] Norme de hiérarchie du système de fichiers. https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
[2] Oui, et parfois les gens font encore des trucs comme ça. Et non, je ne portais ni navet NI oignon à la ceinture.
la source
Si vous exécutez votre script dans un environnement virtuel, par exemple
venv
, l'exécutionwhich python
en travaillant survenv
affichera le chemin vers l'interpréteur Python:~/Envs/venv/bin/python
Notez que le nom de l'environnement virtuel est incorporé dans le chemin d'accès à l'interpréteur Python. Par conséquent, le codage en dur de ce chemin dans votre script entraînera deux problèmes:
Par conséquent, pour ajouter à la réponse de Jonathan , le shebang idéal est
#!/usr/bin/env python
, non seulement pour la portabilité entre les systèmes d'exploitation, mais aussi pour la portabilité entre les environnements virtuels!la source
Compte tenu des problèmes de portabilité entre
python2
etpython3
, vous devez toujours spécifier l'une ou l'autre version, sauf si votre programme est compatible avec les deux.Certaines distributions expédiez un
python
lien symbolique àpython3
un certain temps maintenant - ne comptez pas sur l'python
êtrepython2
.C'est ce que souligne le PEP 394 :
la source
Il indique à l'interpréteur avec quelle version de python exécuter le programme lorsque vous avez plusieurs versions de python.
la source
Il vous permet de sélectionner l'exécutable que vous souhaitez utiliser; ce qui est très pratique si vous avez peut-être plusieurs installations python et différents modules dans chacun et que vous souhaitez choisir. par exemple
la source
cela indique au script où se trouve le répertoire python!
la source