Lorsque j'utilise shebang #!/usr/bin/env python
pour exécuter un script, comment le système sait-il lequel python
utiliser? si je cherche un python
chemin bin dans les variables d'environnement, je ne trouve rien.
env | grep -i python
Lorsque j'utilise shebang #!/usr/bin/env python
pour exécuter un script, comment le système sait-il lequel python
utiliser? si je cherche un python
chemin bin dans les variables d'environnement, je ne trouve rien.
env | grep -i python
Réponses:
Shebang s'attend à ce qu'un chemin d'accès complet à l'interpréteur soit utilisé afin que la syntaxe suivante soit incorrecte:
#!python
Définir un chemin complet comme celui-ci pourrait fonctionner:
#!/usr/local/bin/python
mais serait non portable python peut être installé /bin
, /opt/python/bin
ou un autre endroit où.
En utilisant env
#!/usr/bin/env python
est une méthode permettant à un moyen portable de spécifier au système d’exploitation un chemin complet équivalent à celui où se python
trouve d’abord situé dans PATH
.
La ligne shebang (de «sharp bang», c’est-à-dire #!
) est traitée par le noyau. Le noyau ne veut pas connaître les variables d'environnement telles que PATH
. Donc, le nom sur la ligne shebang doit être un chemin absolu vers un exécutable. Vous pouvez également spécifier un argument supplémentaire à transmettre à cet exécutable avant le nom du script (avec des restrictions dépendant du système, je ne vais pas entrer ici). Par exemple, pour un script Python, vous pouvez spécifier
#!/usr/bin/python
sur la première ligne, et lorsque vous exécutez le script, le noyau s’exécutera /usr/bin/python /path/to/script
. Mais ce n'est pas pratique: vous devez spécifier le chemin complet de la commande. Que faire si vous avez python
dans /usr/bin
sur certaines machines et /usr/local/bin
sur les autres? Ou vous voulez définir votre PATH
à de /home/joe/opt/python-2.5/bin
manière à utiliser une version spécifique de Python? Puisque le noyau ne fait pas la PATH
recherche pour vous, l’idée est de faire en sorte que le noyau exécute une commande qui, à son tour, recherche l’interpréteur souhaité dans PATH
:
#!/fixed/path/to/path-lookup-command python
Cela path-lookup-command
doit prendre le nom d'un exécutable en tant qu'argument, le rechercher PATH
et l'exécuter: le noyau s'exécutera /fixed/path/to/path-lookup-command python /path/to/script
. Il se trouve que la env
commande fait exactement cela. Son objectif principal est d'exécuter une commande dans un environnement différent, mais comme il recherche le nom de la commande $PATH
, il convient parfaitement à notre propos.
Bien que ce ne soit pas officiellement garanti, les systèmes Unix historiques fournis env
dans /usr/bin
, et les systèmes modernes ont gardé cet endroit précisément en raison de l'utilisation généralisée de #!/usr/bin/env
. Ainsi, en pratique, la manière de spécifier qu'un script doit être exécuté par l'interpréteur Python préféré de l'utilisateur est la suivante:
#!/usr/bin/env python
env
et which
? depuis lequel obtiendra également le fichier exécutable le plus éligible de mon environnement PATH.
which
trouve l'exécutable et affiche son chemin. env
trouve le programme spécifié par le premier argument et l'exécute en lui transmettant les arguments restants.
env
version eval which
.
Bon, alors courez:
env | grep PATH
Votre $ PATH est une liste de répertoires. Unix va parcourir cette liste de répertoires, dans l'ordre, jusqu'à ce qu'il trouve "python".
Vous pouvez voir quel répertoire il trouve avec la commande 'which':
which python
sys.path
entre un env $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) et ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
) activés .