Cuando uso el shebang #!/usr/bin/env python
para ejecutar un script, ¿cómo sabe el sistema cuál python
usar? Si busco una python
ruta bin en las variables de entorno, no encuentro nada.
env | grep -i python
Cuando uso el shebang #!/usr/bin/env python
para ejecutar un script, ¿cómo sabe el sistema cuál python
usar? Si busco una python
ruta 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/bin
o 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 python
encuentra 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 python
en /usr/bin
en algunas máquinas y /usr/local/bin
en los demás? O si desea configurar su PATH
a /home/joe/opt/python-2.5/bin
fin de utilizar una versión específica de Python? Como el kernel no buscará PATH
por 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-command
debe tomar el nombre de un archivo ejecutable como argumento y búsquelo en PATH
y ejecutarlo: el núcleo se ejecutará /fixed/path/to/path-lookup-command python /path/to/script
. Como sucede, el env
comando 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 env
en /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
env
y which
? ya que también obtendré el ejecutable más elegible de mi entorno PATH.
which
encuentra el ejecutable e imprime su ruta. env
encuentra el programa especificado por el primer argumento y lo ejecuta, pasándole los argumentos restantes.
env
una versión eval de which
esencialmente.
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.path
entre 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']
).