Cuando uso el shebang #!/usr/bin/env pythonpara ejecutar un script, ¿cómo sabe el sistema cuál pythonusar? Si busco una pythonruta bin en las variables de entorno, no encuentro nada.
env | grep -i python
Cuando uso el shebang #!/usr/bin/env pythonpara ejecutar un script, ¿cómo sabe el sistema cuál pythonusar? Si busco una pythonruta bin en las variables de entorno, no encuentro nada.
env | grep -i python
Respuestas:
El shebang espera una ruta completa para que lo use el intérprete, por lo que la siguiente sintaxis sería incorrecta:
#!python
Establecer una ruta completa como esta podría funcionar:
#!/usr/local/bin/python
pero no sería portátil como pitón podría instalarse en /bin, /opt/python/bino donde sea otra ubicación.
Utilizando env
#!/usr/bin/env python
es un método que permite una forma portátil de especificar al sistema operativo una ruta completa equivalente a la que se pythonencuentra por primera vez en el PATH.
La línea shebang (de "golpe fuerte", es decir #!) es procesada por el núcleo. El núcleo no quiere saber sobre variables de entorno como PATH. Por lo tanto, el nombre en la línea shebang debe ser una ruta absoluta a un ejecutable. También puede especificar un argumento adicional para pasar a ese ejecutable antes del nombre del script (con restricciones dependientes del sistema no entraré aquí). Por ejemplo, para un script de Python, puede especificar
#!/usr/bin/python
en la primera línea, y cuando ejecutas el script, el núcleo se ejecutará de hecho /usr/bin/python /path/to/script. Pero eso no es conveniente: debe especificar la ruta completa del comando. ¿Qué pasa si usted tiene pythonen /usr/binen algunas máquinas y /usr/local/binen los demás? O si desea configurar su PATHa /home/joe/opt/python-2.5/binfin de utilizar una versión específica de Python? Como el kernel no buscará PATHpor usted, la idea es hacer que el kernel ejecute un comando que a su vez busque el intérprete deseado en PATH:
#!/fixed/path/to/path-lookup-command python
Que path-lookup-commanddebe tomar el nombre de un archivo ejecutable como argumento y búsquelo en PATHy ejecutarlo: el núcleo se ejecutará /fixed/path/to/path-lookup-command python /path/to/script. Como sucede, el envcomando hace exactamente eso. Su objetivo principal es ejecutar un comando con un entorno diferente, pero dado que busca el nombre del comando $PATH, es perfecto para nuestro propósito aquí.
Aunque esto no está garantizado oficialmente, los sistemas Unix históricos proporcionados enven /usr/bin, y los sistemas modernos han mantenido a ese lugar precisamente por el uso generalizado de #!/usr/bin/env. Entonces, en la práctica, la forma de especificar que un script debe ser ejecutado por el intérprete de Python favorito del usuario es
#!/usr/bin/env python
envy which? ya que también obtendré el ejecutable más elegible de mi entorno PATH.
whichencuentra el ejecutable e imprime su ruta. envencuentra el programa especificado por el primer argumento y lo ejecuta, pasándole los argumentos restantes.
envuna versión eval de whichesencialmente.
Bien, entonces corre:
env | grep PATH
Su $ PATH es una lista de directorios. Unix revisará esa lista de directorios, en orden, hasta que encuentre "python".
Puedes ver qué directorio encuentra con el comando 'which':
which python
sys.pathentre un env activado $ 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']) y ./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']).