La respuesta a continuación que dice que es solo una línea de comentarios. Ese no es siempre el caso. Tengo un "¡Hola, mundo!" Script CGI (.py) que solo se ejecutará y mostrará la página web #!/usr/bin/env pythonen la parte superior.
He visitado esta publicación muchas veces en 7 años porque a veces olvido el hashbang env. Copiar pasta :)
BugHunterUK
Respuestas:
1084
Si tiene varias versiones de Python instaladas, /usr/bin/envse asegurará de que el intérprete utilizado sea el primero en el entorno.$PATH . La alternativa sería codificar algo así #!/usr/bin/python; está bien, pero menos flexible.
En Unix, un archivo ejecutable que debe interpretarse puede indicar qué intérprete usar al tener un#! al comienzo de la primera línea, seguido del intérprete (y cualquier indicador que pueda necesitar).
Si habla de otras plataformas, por supuesto, esta regla no se aplica (pero esa "línea shebang" no hace daño y ayudará si alguna vez copia ese script en una plataforma con una base Unix, como Linux, Mac , etc.)
Solo para agregar: esto se aplica cuando lo ejecuta en Unix haciéndolo ejecutable ( chmod +x myscript.py) y luego ejecutándolo directamente: en ./myscript.pylugar de solo python myscript.py.
Craig McQueen
28
el uso envproporciona la máxima flexibilidad, ya que el usuario puede seleccionar el intérprete para usar cambiando la RUTA. Sin embargo, a menudo esta flexibilidad no es necesaria y la desventaja es que Linux, por ejemplo, no puede usar el nombre del script para el nombre del proceso psy vuelve a "python". Al empaquetar aplicaciones de Python para distribuciones, por ejemplo, recomendaría no usar env.
Una palabra importante de advertencia, el valor de retorno de env finalmente expira. Es poco probable que lo afecte si está ejecutando procesos de corta duración. Sin embargo, he tenido procesos que mueren con el mensaje /usr/bin/env: Key has expireddespués de muchas horas.
malaverdiere
44
@malaverdiere, ¿puede vincular a algún recurso que explique este comportamiento de vencimiento? No los puedo encontrar.
En informática, un shebang (también llamado hashbang, hashpling, pound bang o crunchbang) se refiere a los caracteres "#!" cuando son los dos primeros caracteres en una directiva de intérprete como la primera línea de un archivo de texto. En un sistema operativo tipo Unix, el cargador de programas toma la presencia de estos dos caracteres como una indicación de que el archivo es un script e intenta ejecutar ese script utilizando el intérprete especificado por el resto de la primera línea del archivo.
Incluso en Windows, donde la línea shebang no determina el intérprete que se ejecutará, puede pasar opciones al intérprete al especificarlas en la línea shebang. Me resulta útil mantener una línea shebang genérica en scripts únicos (como los que escribo al responder preguntas en SO), para poder probarlos rápidamente en Windows y ArchLinux .
El primer argumento restante especifica el nombre del programa a invocar; se busca según la PATHvariable de entorno. Cualquier argumento restante se pasa como argumento a ese programa.
Fácil de encontrar con Google, si se conocen las palabras clave (la "línea shebang" es esencial).
Arafangion
14
En realidad, esta explicación es más clara que otras referencias que verifiqué con Google. Siempre es mejor obtener una explicación de 1 párrafo dirigida a la pregunta, en lugar de leer un manual completo que aborde cada uso potencial.
@ulidtko: Interesante motor de búsqueda, considere escribir una respuesta para que la pregunta de John García tenga una mejor respuesta.
Arafangion
1
"Incluso en Windows, donde la línea shebang no determina el intérprete que se debe ejecutar, puede pasar opciones al intérprete al especificarlas en la línea shebang". Eso es simplemente falso; Si sucede algo así, es porque el propio intérprete está procesando la línea shebang. Si el intérprete no tiene un reconocimiento especial para las líneas shebang, entonces no sucede tal cosa. Windows no hace nada con líneas shebang ". Lo que puede estar describiendo en este caso es el lanzador de python: python.org/dev/peps/pep-0397 .
Kaz
154
Ampliando un poco las otras respuestas, aquí hay un pequeño ejemplo de cómo sus scripts de línea de comando pueden meterse en problemas por el uso incauto de las /usr/bin/envlíneas shebang:
Una forma de protegerse contra ese tipo de problema es usar los nombres de comandos de Python versionados que normalmente se instalan con la mayoría de las Pythons:
Diferencia entre local y global. Si which pythonvuelve /usr/bin/python, una ruta de directorio local podría estar codificado: #!/usr/bin/python. Pero eso es menos flexible que el #!/usr/bin/env pythonque tiene una aplicación global.
noobninja
85
Para ejecutar el script de Python, necesitamos decirle al shell tres cosas:
Que el archivo es un script
A qué intérprete queremos ejecutar el script
El camino de dicho intérprete
El shebang #!cumple (1.). El shebang comienza con un #porque el #personaje es un marcador de comentario en muchos lenguajes de secuencias de comandos. Por lo tanto, el intérprete ignora automáticamente el contenido de la línea shebang.
El envcomando cumple (2.) y (3.). Para citar "gravedad",
Un uso común del envcomando es lanzar intérpretes, haciendo uso del hecho de que env buscará en $ PATH el comando que se le indica que inicie. Dado que la línea shebang requiere que se especifique una ruta absoluta y que la ubicación de varios intérpretes (perl, bash, python) puede variar mucho, es común usar:
#!/usr/bin/env perl en lugar de tratar de adivinar si es / bin / perl, / usr / bin / perl, / usr / local / bin / perl, / usr / local / pkg / perl, / fileserver / usr / bin / perl, o / home / MrDaniel / usr / bin / perl en el sistema del usuario ...
Por otro lado, env casi siempre está en / usr / bin / env. (Excepto en los casos en que no lo es; algunos sistemas pueden usar / bin / env, pero esa es una ocasión bastante rara y solo ocurre en sistemas que no son Linux).
No necesitas esa línea en absoluto. El sistema llamará a python y luego el intérprete de python ejecutará su script.
Pero si tiene la intención de usar: $./myscript.py
Al llamarlo directamente como un programa normal o un script bash, debe escribir esa línea para especificar al sistema qué programa usar para ejecutarlo (y también hacer que sea ejecutable con chmod 755)
Lee los primeros bytes del archivo y los compara con #!.
Si la comparación es verdadera, el núcleo de Linux analiza el resto de la línea, que realiza otra execllamada con la ruta /usr/bin/env pythony el archivo actual como primer argumento:
/usr/bin/env python /path/to/script.py
y esto funciona para cualquier lenguaje de secuencias de comandos que se use #como carácter de comentario.
Y sí, puedes hacer un ciclo infinito con:
printf '#!/a\n'| sudo tee /a
sudo chmod +x /a
/a
Bash reconoce el error:
-bash:/a: /a: bad interpreter:Too many levels of symbolic links
#! Simplemente resulta ser legible para los humanos, pero eso no es obligatorio.
Si el archivo comenzó con diferentes bytes, la execllamada al sistema usaría un controlador diferente. El otro controlador incorporado más importante es para archivos ejecutables ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 que comprueba los bytes 7f 45 4c 46(que también son humanos legible para .ELF). Confirmemos eso leyendo los 4 primeros bytes de /bin/ls, que es un ejecutable ELF:
Sin embargo , no creo que POSIX especifique shebangs: https://unix.stackexchange.com/a/346214/32558 , aunque sí menciona en las secciones de justificación, y en la forma "si el sistema admite scripts ejecutables, algo puede suceder". macOS y FreeBSD también parecen implementarlo sin embargo.
PATH buscar motivación
Probablemente, una gran motivación para la existencia de shebangs es el hecho de que en Linux, a menudo queremos ejecutar comandos desde PATH:
basename-of-command
en vez de:
/full/path/to/basename-of-command
Pero entonces, sin el mecanismo shebang, ¿cómo sabría Linux cómo iniciar cada tipo de archivo?
Codificar la extensión en comandos:
basename-of-command.py
o implementar la búsqueda PATH en cada intérprete:
python basename-of-command
sería una posibilidad, pero este tiene el principal problema de que todo se rompe si alguna vez decidimos refactorizar el comando a otro idioma.
Los shebangs resuelven este problema maravillosamente.
Técnicamente, en Python, esto es solo una línea de comentarios.
Esta línea solo se usa si ejecuta el script py desde el shell (desde la línea de comando). Esto se conoce como el " Shebang !" , y se usa en varias situaciones, no solo con scripts de Python.
Aquí, le indica al shell que inicie una versión específica de Python (para encargarse del resto del archivo.
El shebang es un concepto de Unix. Vale la pena mencionar que también funciona en Windows si ha instalado el iniciador de Pythonpy.exe . Esto es parte de una instalación estándar de Python.
florisla
38
La razón principal para hacer esto es hacer que el script sea portátil en todos los entornos del sistema operativo.
Por ejemplo, bajo mingw, los scripts de python usan:
#!/c/python3k/python
y bajo distribución GNU / Linux es:
#!/usr/local/bin/python
o
#!/usr/bin/python
y bajo el mejor sistema comercial Unix sw / hw de todos (OS / X), es:
#!/Applications/MacPython 2.5/python
o en FreeBSD:
#!/usr/local/bin/python
Sin embargo, todas estas diferencias pueden hacer que el script sea portátil a través de todos al usar:
Bajo MacOSX, también lo es /usr/bin/python. Bajo Linux, el Python instalado por el sistema también es casi seguro /usr/bin/python(nunca he visto nada más y no tendría sentido). Tenga en cuenta que puede haber sistemas que no tienen /usr/bin/env.
Albert
1
Si está en OSX y usa Homebrew y sigue sus instrucciones de instalación predeterminadas, estará en #! / Usr / local / bin / python
Será
@ Jean-PaulCalderone: Vea la respuesta de saaj a continuación.
pydsigner
Actualización para el año 2018: Bare pythonno es tan portátil, es el intérprete predeterminado de distribución de Python. Arch Linux por defecto es Python 3 durante mucho tiempo y es posible que las distribuciones también lo piensen porque Python 2 solo es compatible hasta 2020.
mati865
22
Probablemente tenga sentido enfatizar una cosa que la mayoría se ha perdido, lo que puede impedir la comprensión inmediata. Cuando escribe pythonen la terminal, normalmente no proporciona una ruta completa. En cambio, el ejecutable se busca en PATHla variable de entorno. A su vez, cuando desea ejecutar un programa Python directamente, /path/to/app.pyuno debe decirle al intérprete qué intérprete usar (a través del hashbang , lo que los otros contribuyentes están explicando anteriormente).
Hashbang espera el camino completo a un intérprete. Por lo tanto, para ejecutar su programa Python directamente, debe proporcionar la ruta completa al binario de Python que varía significativamente, especialmente considerando el uso de virtualenv . Para abordar la portabilidad /usr/bin/envse utiliza el truco con . Este último está destinado originalmente a alterar el entorno en el lugar y ejecutar un comando en él. Cuando no se proporciona ninguna alteración, ejecuta el comando en el entorno actual, lo que efectivamente resulta en la misma PATHbúsqueda que hace el truco.
Solo especifica qué intérprete desea utilizar. Para comprender esto, cree un archivo a través de la terminal haciendo touch test.py, luego escriba en ese archivo lo siguiente:
#!/usr/bin/env python3print"test"
y haz chmod +x test.pyque tu script sea ejecutable. Después de esto, cuando lo haga ./test.py, debería recibir un error que diga:
File"./test.py", line 2print"test"^SyntaxError:Missing parentheses in call to 'print'
porque python3 no admite el operador de impresión.
Ahora continúe y cambie la primera línea de su código a:
#!/usr/bin/env python2
y funcionará, imprimiendo testen stdout, porque python2 es compatible con el operador de impresión. Entonces, ahora has aprendido a cambiar entre intérpretes de guiones.
Me parece que los archivos se ejecutan igual sin esa línea.
Si es así, ¿tal vez estás ejecutando el programa Python en Windows? Windows no usa esa línea; en su lugar, usa la extensión de nombre de archivo para ejecutar el programa asociado con la extensión de archivo.
Sin embargo, en 2011, se desarrolló un "iniciador de Python" que (hasta cierto punto) imita este comportamiento de Linux para Windows. Esto se limita solo a elegir qué intérprete de Python se ejecuta, por ejemplo, para seleccionar entre Python 2 y Python 3 en un sistema donde ambos están instalados. El iniciador se instala opcionalmente como py.exemediante la instalación de Python, y puede asociarse con .pyarchivos para que el iniciador verifique esa línea y, a su vez, inicie la versión del intérprete de Python especificada.
Él también podría estar usando $ python myscript.py.
Sinan Ünür
Cometí el error al no tener la línea y usé python script.py, y un día simplemente hice ./myscript.py y todo dejó de funcionar, luego me di cuenta de que el sistema está buscando el archivo como un script de shell en lugar de un script de python.
Guagua
8
Esto significa más información histórica que una respuesta "real".
Recuerda que en su día que tenían un montón de sistemas operativos tipo UNIX cuyos diseñadores todos tenían su propia idea de dónde colocar las cosas, ya veces no incluía Python, Perl, Bash, o un montón de otros GNU / Open Source cosas en absoluto .
Esto fue incluso cierto para diferentes distribuciones de Linux. En Linux - pre-FHS [1] -puede tener python en / usr / bin / o / usr / local / bin /. O puede que no se haya instalado, por lo que creó el suyo propio y lo colocó en ~ / bin
Solaris fue el peor en el que he trabajado, en parte como la transición de Berkeley Unix al Sistema V. Podría terminar con cosas en / usr /, / usr / local /, / usr / ucb, / opt / etc. Esto podría hacer que por algunos caminos realmente largos. Tengo recuerdos de las cosas de Sunfreeware.com instalando cada paquete en su propio directorio, pero no recuerdo si unía los enlaces binarios a / usr / bin o no.
Ah, y a veces / usr / bin estaba en un servidor NFS [2].
Entonces, la envutilidad fue desarrollada para solucionar esto.
Entonces podías escribir #!/bin/env interpretery mientras el camino fuera correcto, las cosas tenían una posibilidad razonable de correr. Por supuesto, razonable significaba (para Python y Perl) que también había establecido las variables ambientales apropiadas. Para bash / ksh / zsh simplemente funcionó.
Esto era importante porque la gente pasaba por scripts de shell (como perl y python) y si codificabas / usr / bin / python en tu estación de trabajo Red Hat Linux, se rompería mal en un SGI ... bueno, no , Creo que IRIX puso a Python en el lugar correcto. Pero en una estación Sparc podría no funcionar en absoluto.
Echo de menos mi estación de sparc. Pero no mucho. Ok, ahora me tienes dando vueltas en E-Bay. Bastajes
Si está ejecutando su script en un entorno virtual, por ejemplo venv, al ejecutar which pythonmientras trabaja, venvse mostrará la ruta al intérprete de Python:
~/Envs/venv/bin/python
Tenga en cuenta que el nombre del entorno virtual está incrustado en la ruta al intérprete de Python. Por lo tanto, codificar esta ruta en su script causará dos problemas:
Si carga el script en un repositorio, está obligando a otros usuarios a tener el mismo nombre de entorno virtual . Esto es si primero identifican el problema.
No podrá ejecutar el script en varios entornos virtuales, incluso si tuviera todos los paquetes necesarios en otros entornos virtuales.
Por lo tanto, para agregar a la respuesta de Jonathan , ¡el shebang ideal es #!/usr/bin/env python, no solo para la portabilidad entre sistemas operativos, sino también para la portabilidad en entornos virtuales!
Teniendo en cuenta los problemas de portabilidad entre python2y python3, siempre debe especificar cualquiera de las versiones a menos que su programa sea compatible con ambas.
Algunas distribuciones se envían por pythonenlaces simbólicos python3desde hace un tiempo, no confíes en pythonser python2.
Para tolerar diferencias entre plataformas, todo el código nuevo que necesita invocar al intérprete de Python no debe especificar python, sino que debe especificar python2 o python3 (o las versiones más específicas de python2.xy python3.x; consulte las Notas de migración ) . Esta distinción debe hacerse en shebangs, cuando se invoca desde un script de shell, cuando se invoca a través de la llamada system (), o cuando se invoca en cualquier otro contexto.
Le permite seleccionar el ejecutable que desea usar; lo cual es muy útil si quizás tiene varias instalaciones de Python y diferentes módulos en cada una y desea elegir. p.ej
#!/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
en la parte superior.Respuestas:
Si tiene varias versiones de Python instaladas,
/usr/bin/env
se asegurará de que el intérprete utilizado sea el primero en el entorno.$PATH
. La alternativa sería codificar algo así#!/usr/bin/python
; está bien, pero menos flexible.En Unix, un archivo ejecutable que debe interpretarse puede indicar qué intérprete usar al tener un
#!
al comienzo de la primera línea, seguido del intérprete (y cualquier indicador que pueda necesitar).Si habla de otras plataformas, por supuesto, esta regla no se aplica (pero esa "línea shebang" no hace daño y ayudará si alguna vez copia ese script en una plataforma con una base Unix, como Linux, Mac , etc.)
fuente
chmod +x myscript.py
) y luego ejecutándolo directamente: en./myscript.py
lugar de solopython myscript.py
.env
proporciona la máxima flexibilidad, ya que el usuario puede seleccionar el intérprete para usar cambiando la RUTA. Sin embargo, a menudo esta flexibilidad no es necesaria y la desventaja es que Linux, por ejemplo, no puede usar el nombre del script para el nombre del procesops
y vuelve a "python". Al empaquetar aplicaciones de Python para distribuciones, por ejemplo, recomendaría no usarenv
.py
El lanzador puede usar la línea shebang en Windows. Se incluye en Python 3.3 o se puede instalar de forma independiente ./usr/bin/env: Key has expired
después de muchas horas.Eso se llama la línea shebang . Como explica la entrada de Wikipedia :
Consulte también la entrada de Preguntas frecuentes de Unix .
Incluso en Windows, donde la línea shebang no determina el intérprete que se ejecutará, puede pasar opciones al intérprete al especificarlas en la línea shebang. Me resulta útil mantener una línea shebang genérica en scripts únicos (como los que escribo al responder preguntas en SO), para poder probarlos rápidamente en Windows y ArchLinux .
La utilidad env le permite invocar un comando en la ruta:
fuente
Ampliando un poco las otras respuestas, aquí hay un pequeño ejemplo de cómo sus scripts de línea de comando pueden meterse en problemas por el uso incauto de las
/usr/bin/env
líneas shebang:El módulo json no existe en Python 2.5.
Una forma de protegerse contra ese tipo de problema es usar los nombres de comandos de Python versionados que normalmente se instalan con la mayoría de las Pythons:
Si solo necesita distinguir entre Python 2.xy Python 3.x, las versiones recientes de Python 3 también proporcionan un
python3
nombre:fuente
which python
vuelve/usr/bin/python
, una ruta de directorio local podría estar codificado:#!/usr/bin/python
. Pero eso es menos flexible que el#!/usr/bin/env python
que tiene una aplicación global.Para ejecutar el script de Python, necesitamos decirle al shell tres cosas:
El shebang
#!
cumple (1.). El shebang comienza con un#
porque el#
personaje es un marcador de comentario en muchos lenguajes de secuencias de comandos. Por lo tanto, el intérprete ignora automáticamente el contenido de la línea shebang.El
env
comando cumple (2.) y (3.). Para citar "gravedad",fuente
Quizás su pregunta es en este sentido:
Si quieres usar:
$python myscript.py
No necesitas esa línea en absoluto. El sistema llamará a python y luego el intérprete de python ejecutará su script.
Pero si tiene la intención de usar:
$./myscript.py
Al llamarlo directamente como un programa normal o un script bash, debe escribir esa línea para especificar al sistema qué programa usar para ejecutarlo (y también hacer que sea ejecutable con
chmod 755
)fuente
La
exec
llamada al sistema del kernel de Linux comprende shebangs (#!
) de forma nativaCuando lo haces en bash:
en Linux, esto llama a la
exec
llamada del sistema con la ruta./something
.Esta línea del núcleo se llama en el archivo pasado a
exec
: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25Lee los primeros bytes del archivo y los compara con
#!
.Si la comparación es verdadera, el núcleo de Linux analiza el resto de la línea, que realiza otra
exec
llamada con la ruta/usr/bin/env python
y el archivo actual como primer argumento:y esto funciona para cualquier lenguaje de secuencias de comandos que se use
#
como carácter de comentario.Y sí, puedes hacer un ciclo infinito con:
Bash reconoce el error:
#!
Simplemente resulta ser legible para los humanos, pero eso no es obligatorio.Si el archivo comenzó con diferentes bytes, la
exec
llamada al sistema usaría un controlador diferente. El otro controlador incorporado más importante es para archivos ejecutables ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 que comprueba los bytes7f 45 4c 46
(que también son humanos legible para.ELF
). Confirmemos eso leyendo los 4 primeros bytes de/bin/ls
, que es un ejecutable ELF:salida:
Entonces, cuando el kernel ve esos bytes, toma el archivo ELF, lo guarda en la memoria correctamente y comienza un nuevo proceso con él. Ver también: ¿Cómo obtiene el núcleo un archivo binario ejecutable que se ejecuta en Linux?
Finalmente, puede agregar sus propios manejadores de shebang con el
binfmt_misc
mecanismo. Por ejemplo, puede agregar un controlador personalizado para.jar
archivos . Este mecanismo incluso admite controladores por extensión de archivo. Otra aplicación es ejecutar de forma transparente ejecutables de una arquitectura diferente con QEMU .Sin embargo , no creo que POSIX especifique shebangs: https://unix.stackexchange.com/a/346214/32558 , aunque sí menciona en las secciones de justificación, y en la forma "si el sistema admite scripts ejecutables, algo puede suceder". macOS y FreeBSD también parecen implementarlo sin embargo.
PATH
buscar motivaciónProbablemente, una gran motivación para la existencia de shebangs es el hecho de que en Linux, a menudo queremos ejecutar comandos desde
PATH
:en vez de:
Pero entonces, sin el mecanismo shebang, ¿cómo sabría Linux cómo iniciar cada tipo de archivo?
Codificar la extensión en comandos:
o implementar la búsqueda PATH en cada intérprete:
sería una posibilidad, pero este tiene el principal problema de que todo se rompe si alguna vez decidimos refactorizar el comando a otro idioma.
Los shebangs resuelven este problema maravillosamente.
fuente
Técnicamente, en Python, esto es solo una línea de comentarios.
Esta línea solo se usa si ejecuta el script py desde el shell (desde la línea de comando). Esto se conoce como el " Shebang !" , y se usa en varias situaciones, no solo con scripts de Python.
Aquí, le indica al shell que inicie una versión específica de Python (para encargarse del resto del archivo.
fuente
py.exe
. Esto es parte de una instalación estándar de Python.La razón principal para hacer esto es hacer que el script sea portátil en todos los entornos del sistema operativo.
Por ejemplo, bajo mingw, los scripts de python usan:
y bajo distribución GNU / Linux es:
o
y bajo el mejor sistema comercial Unix sw / hw de todos (OS / X), es:
o en FreeBSD:
Sin embargo, todas estas diferencias pueden hacer que el script sea portátil a través de todos al usar:
fuente
/usr/bin/python
. Bajo Linux, el Python instalado por el sistema también es casi seguro/usr/bin/python
(nunca he visto nada más y no tendría sentido). Tenga en cuenta que puede haber sistemas que no tienen/usr/bin/env
.python
no es tan portátil, es el intérprete predeterminado de distribución de Python. Arch Linux por defecto es Python 3 durante mucho tiempo y es posible que las distribuciones también lo piensen porque Python 2 solo es compatible hasta 2020.Probablemente tenga sentido enfatizar una cosa que la mayoría se ha perdido, lo que puede impedir la comprensión inmediata. Cuando escribe
python
en la terminal, normalmente no proporciona una ruta completa. En cambio, el ejecutable se busca enPATH
la variable de entorno. A su vez, cuando desea ejecutar un programa Python directamente,/path/to/app.py
uno debe decirle al intérprete qué intérprete usar (a través del hashbang , lo que los otros contribuyentes están explicando anteriormente).Hashbang espera el camino completo a un intérprete. Por lo tanto, para ejecutar su programa Python directamente, debe proporcionar la ruta completa al binario de Python que varía significativamente, especialmente considerando el uso de virtualenv . Para abordar la portabilidad
/usr/bin/env
se utiliza el truco con . Este último está destinado originalmente a alterar el entorno en el lugar y ejecutar un comando en él. Cuando no se proporciona ninguna alteración, ejecuta el comando en el entorno actual, lo que efectivamente resulta en la mismaPATH
búsqueda que hace el truco.Fuente de unix stackexchange
fuente
Esta es una convención de shell que le dice al shell qué programa puede ejecutar el script.
resuelve una ruta al binario de Python.
fuente
Es la forma recomendada, propuesta en la documentación:
de http://docs.python.org/py3k/tutorial/interpreter.html#executable-python-scripts
fuente
Puedes probar este problema usando virtualenv
Aquí está test.py
Crea ambientes virtuales
active cada entorno y luego verifique las diferencias
fuente
Solo especifica qué intérprete desea utilizar. Para comprender esto, cree un archivo a través de la terminal haciendo
touch test.py
, luego escriba en ese archivo lo siguiente:y haz
chmod +x test.py
que tu script sea ejecutable. Después de esto, cuando lo haga./test.py
, debería recibir un error que diga:porque python3 no admite el operador de impresión.
Ahora continúe y cambie la primera línea de su código a:
y funcionará, imprimiendo
test
en stdout, porque python2 es compatible con el operador de impresión. Entonces, ahora has aprendido a cambiar entre intérpretes de guiones.fuente
Si es así, ¿tal vez estás ejecutando el programa Python en Windows? Windows no usa esa línea; en su lugar, usa la extensión de nombre de archivo para ejecutar el programa asociado con la extensión de archivo.
Sin embargo, en 2011, se desarrolló un "iniciador de Python" que (hasta cierto punto) imita este comportamiento de Linux para Windows. Esto se limita solo a elegir qué intérprete de Python se ejecuta, por ejemplo, para seleccionar entre Python 2 y Python 3 en un sistema donde ambos están instalados. El iniciador se instala opcionalmente como
py.exe
mediante la instalación de Python, y puede asociarse con.py
archivos para que el iniciador verifique esa línea y, a su vez, inicie la versión del intérprete de Python especificada.fuente
$ python myscript.py
.Esto significa más información histórica que una respuesta "real".
Recuerda que en su día que tenían un montón de sistemas operativos tipo UNIX cuyos diseñadores todos tenían su propia idea de dónde colocar las cosas, ya veces no incluía Python, Perl, Bash, o un montón de otros GNU / Open Source cosas en absoluto .
Esto fue incluso cierto para diferentes distribuciones de Linux. En Linux - pre-FHS [1] -puede tener python en / usr / bin / o / usr / local / bin /. O puede que no se haya instalado, por lo que creó el suyo propio y lo colocó en ~ / bin
Solaris fue el peor en el que he trabajado, en parte como la transición de Berkeley Unix al Sistema V. Podría terminar con cosas en / usr /, / usr / local /, / usr / ucb, / opt / etc. Esto podría hacer que por algunos caminos realmente largos. Tengo recuerdos de las cosas de Sunfreeware.com instalando cada paquete en su propio directorio, pero no recuerdo si unía los enlaces binarios a / usr / bin o no.
Ah, y a veces / usr / bin estaba en un servidor NFS [2].
Entonces, la
env
utilidad fue desarrollada para solucionar esto.Entonces podías escribir
#!/bin/env interpreter
y mientras el camino fuera correcto, las cosas tenían una posibilidad razonable de correr. Por supuesto, razonable significaba (para Python y Perl) que también había establecido las variables ambientales apropiadas. Para bash / ksh / zsh simplemente funcionó.Esto era importante porque la gente pasaba por scripts de shell (como perl y python) y si codificabas / usr / bin / python en tu estación de trabajo Red Hat Linux, se rompería mal en un SGI ... bueno, no , Creo que IRIX puso a Python en el lugar correcto. Pero en una estación Sparc podría no funcionar en absoluto.
Echo de menos mi estación de sparc. Pero no mucho. Ok, ahora me tienes dando vueltas en E-Bay. Bastajes
[1] Estándar de jerarquía del sistema de archivos. https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
[2] Sí, y a veces la gente todavía hace cosas así. Y no, no llevaba ni un nabo ni una cebolla en el cinturón.
fuente
Si está ejecutando su script en un entorno virtual, por ejemplo
venv
, al ejecutarwhich python
mientras trabaja,venv
se mostrará la ruta al intérprete de Python:~/Envs/venv/bin/python
Tenga en cuenta que el nombre del entorno virtual está incrustado en la ruta al intérprete de Python. Por lo tanto, codificar esta ruta en su script causará dos problemas:
Por lo tanto, para agregar a la respuesta de Jonathan , ¡el shebang ideal es
#!/usr/bin/env python
, no solo para la portabilidad entre sistemas operativos, sino también para la portabilidad en entornos virtuales!fuente
Teniendo en cuenta los problemas de portabilidad entre
python2
ypython3
, siempre debe especificar cualquiera de las versiones a menos que su programa sea compatible con ambas.Algunas distribuciones se envían por
python
enlaces simbólicospython3
desde hace un tiempo, no confíes enpython
serpython2
.PEP 394 enfatiza esto :
fuente
Le dice al intérprete con qué versión de python ejecutar el programa cuando tiene varias versiones de python.
fuente
Le permite seleccionar el ejecutable que desea usar; lo cual es muy útil si quizás tiene varias instalaciones de Python y diferentes módulos en cada una y desea elegir. p.ej
fuente
¡Esto le dice al script dónde está el directorio de Python!
fuente