web-dev-qa-db-fra.com

Comment / usr / bin / env sait-il quel programme utiliser?

Lorsque j'utilise le Shebang #!/usr/bin/env python pour exécuter un script, comment le système sait-il quel python utiliser? si je recherche un chemin bin python dans les variables d'environnement je ne trouve rien.

env | grep -i python
65
tMC

Le Shebang attend un chemin complet vers l'interpréteur à utiliser, de sorte que la syntaxe suivante serait incorrecte:

#!python

Définir un chemin complet comme celui-ci pourrait fonctionner:

#!/usr/local/bin/python

mais serait non portable car python pourrait être installé dans /bin, /opt/python/bin, ou partout ailleurs.

Utilisation de env

#!/usr/bin/env python

est une méthode permettant à un système portable de spécifier au système d'exploitation un chemin complet équivalent à celui où python est situé pour la première fois dans PATH.

55
jlliagre

La ligne Shebang (à partir de "coup sec", c'est-à-dire #!) est traité par le noyau. Le noyau ne veut pas connaître les variables d'environnement telles que PATH. Le nom sur la ligne Shebang doit donc être un chemin absolu vers un exécutable. Vous pouvez également spécifier un argument supplémentaire à passer à cet exécutable avant le nom du script (avec des restrictions dépendant du système, je n'entrerai pas 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 exécutera en fait /usr/bin/python /path/to/script. Mais ce n'est pas pratique: vous devez spécifier le chemin complet de la commande. Et si vous avez python dans /usr/bin sur certaines machines et /usr/local/bin sur les autres? Ou vous souhaitez définir votre PATH sur /home/joe/opt/python-2.5/bin pour utiliser une version spécifique de Python? Puisque le noyau ne fera pas la recherche PATH pour vous, l'idée est de faire exécuter au noyau une commande qui à son tour recherche l'interpréteur souhaité dans le PATH:

#!/fixed/path/to/path-lookup-command python

Cette path-lookup-command doit prendre le nom d'un exécutable comme argument et le rechercher dans PATH et l'exécuter: le noyau exécutera /fixed/path/to/path-lookup-command python /path/to/script. En l'occurrence, la commande env fait exactement cela. Son objectif principal est d'exécuter une commande avec un environnement différent, mais comme elle recherche le nom de la commande dans $PATH, c'est parfait pour notre objectif ici.

Bien que cela ne soit pas officiellement garanti, les systèmes Unix historiques fournissaient env dans /usr/bin, et les systèmes modernes ont conservé cet emplacement précisément en raison de l'utilisation généralisée de #!/usr/bin/env. Donc, en pratique, la façon de spécifier qu'un script doit être exécuté par l'interpréteur préféré de l'utilisateur Python est

#!/usr/bin/env python

Bon, alors lancez:

env | grep PATH

Votre $ PATH est une liste de répertoires. Unix parcourra 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
7
Dan Rue