¿Por qué Python en Linux requiere la línea #! / Usr / bin / python?

50

Pregunta bastante simple: en Linux, ¿por qué Python requiere la línea?

#!/usr/bin/python

al comienzo de un archivo python, ya que Windows no?

¿Qué hace? porque la descripción "Enlaces a Python" es un poco vaga ...

Dime por qué
fuente
28
Las respuestas a continuación son correctas, ninguna de ellas explica por qué Windows no necesita esta línea. Windows depende de la extensión del archivo (la parte después de la .) para determinar qué tipo de archivo es. Incluso Windows se está alejando de esto: examine las primeras líneas del archivo de Microsoft Word, y dirá que, de hecho, es un archivo de Microsoft Word.
Charles Green
99
El elefante en la habitación es que NUNCA debes usar / usr / bin / python a menos que seas compatible con python 2 y 3. Motivo: archiva los enlaces simbólicos a python3, un movimiento que es reconocido por la PSF, que recomienda no hacerlo.
Otro usuario más
55
Está implícito, pero no se indica explícitamente en las respuestas a continuación que no es obligatorio . Es obligatorio si desea ejecutar el script solo desde su propio nombre. Siempre puedes correr en su python myscript.pylugar.
Chris H
3
@CharlesGreen no se supone que sepamos por qué Windows no lo hace ;-) Eso depende de SO.
Rinzwind
2
@YetAnotherUser Han pasado seis años y once meses desde que se lanzó Python 3, en este punto creo que sería mejor que la gente deje de usar 3 y especifique explícitamente el uso de 2 cuando sea necesario.
JAB

Respuestas:

58

Python no tiene ningún requisito especial en Linux. Es el cargador de programas en Unix / Linux que utiliza la línea "shebang", como se le llama. Esto es en realidad una característica más que una limitación, pero llegaremos a eso en un momento. La página Wiki sobre "shebang" tiene más detalles, pero intentaré dar una visión general, así como una comparación con Windows aquí.

Primero, veamos la situación en Windows:

  • Cuando intenta abrir o ejecutar un archivo, Windows primero examina la extensión de ese archivo. Esta es la última parte del nombre de archivo que comienza en .En el caso de los archivos Python, esto es típicamente .py.
  • Windows busca qué acción tomar según la extensión del archivo.
    • Esta información se registra en el registro de Windows; cuando se instala Python, generalmente le dice a Windows que los .pyarchivos deben abrirse utilizando la aplicación Python recién instalada (es decir, el intérprete de Python).
    • Varios tipos de archivos tienen comportamientos integrados; por ejemplo, los archivos ejecutables (como el propio intérprete de Python) deben terminar .exey los .batarchivos se ejecutan como scripts por lotes de Windows.
    • La acción tomada para un tipo de archivo en particular es personalizable . Puede, por ejemplo, decirle a Windows que en lugar de ejecutar .pyarchivos usando python.exe, debería abrirlos con algún otro programa, como el editor de texto notepad.exe.
      • En este caso, para ejecutar una secuencia de comandos de Python, deberá llamar manualmentepython <scriptname>.py (o escribir un .batarchivo para que lo haga por usted).

Ahora, ¿qué sucede si hay una línea shebang ( #!/usr/bin/pythono #!/usr/bin/env python) en la parte superior del script de Python? Bueno, dado que #es una línea de comentarios en Python, el intérprete de Python simplemente la ignora. Esta es una de las razones por las cuales la mayoría de los lenguajes de script utilizados en el mundo Unix / Linux se utilizan #para iniciar líneas de comentarios.

Por lo tanto, es un poco engañoso decir que Windows "no necesita" la #!línea; Windows no ve la #!línea, y de hecho se basa en la extensión de archivo para decirle qué hacer. Esto tiene un par de desventajas:

  • Usted debe nombrar con scripts de Python .pyen el extremo con el fin de que sean reconocidas automáticamente como tal.
  • No hay una manera fácil de distinguir los scripts Python2 de los scripts Python3.
  • Como se señaló anteriormente, si cambia el comportamiento de inicio predeterminado para el .pytipo de archivo, Windows ya no ejecutará automáticamente esos scripts con Python. Tenga en cuenta que esto podría hacerse sin querer.

Ahora, veamos cómo Unix / Linux lanza scripts:

Lo primero a tener en cuenta es que Unix / Linux, a diferencia de Windows, no está tratando de "abrir" scripts de Python utilizando un programa en particular, al menos conceptualmente; el sistema operativo sabe que el script es algo que se puede ejecutar debido a algo llamado "bit de ejecución" (que está fuera del alcance de esta respuesta). Entonces, si escribe accidentalmente en #!/usr/bin/pthonlugar de #!/usr/bin/python, recibirá un mensaje de error que incluye este texto:

/usr/bin/pthon: bad interpreter: No such file or directory.

La palabra "intérprete" nos da una pista sobre el papel de la línea shebang (aunque técnicamente el programa especificado puede ser algo más que un intérprete, como catun editor de texto). Cuando intentas ejecutar un archivo, esto es lo que sucede:

  • El cargador del programa Unix / Linux mira los primeros dos bytes de ese archivo; si estos dos bytes son #!, entonces el cargador interpreta el resto de la línea shebang (excluyendo el shebang en sí) como un comando para iniciar un intérprete con el que ejecutar el contenido del archivo como un script.
  • El cargador del programa inicia el intérprete especificado y le proporciona la ruta del archivo original como argumento.

Esto tiene un par de ventajas:

  • El guionista tiene más control sobre qué intérprete se utilizará (lo que resuelve el problema de Python2 / Python3) y, en ocasiones, puede pasar un argumento adicional al intérprete (consulte la página Wiki para obtener más detalles).
  • El nombre de archivo de la secuencia de comandos se ignora , por lo que puede nombrar las secuencias de comandos de Python como desee.

Tenga en cuenta, finalmente, que Unix / Linux no necesita la línea shebang para ejecutar un script Python. Recuerde que todo lo que hace la línea shebang es permitir que el cargador del programa seleccione un intérprete. Pero al igual que en Windows, esto se puede hacer manualmente:

python <myscript>
Kyle Strand
fuente
1
En Windows usted podría tener fácilmente .py2y .py3extensiones para Python 2 / Python 3 guiones. Entonces, tanto Linux (+ x bit) como Windows (extensión de archivo) necesitan metadatos en el sistema de archivos. La principal diferencia es que el bit + x se pierde más fácilmente en tránsito. Esto no es necesariamente un inconveniente.
MSalters
1
@MSalters El bit de ejecución también tiene mucha menos información codificada en él. Y tenga en cuenta que puede tener múltiples intérpretes de Python2 en un sistema dado (hubo una situación similar con Ruby y otros idiomas en un trabajo mío anterior); lidiar con esto a través de la línea shebang es casi trivial, mientras que la situación en Windows se vuelve mucho menos manejable cuanto más intentas administrar múltiples tipos de archivos similares.
Kyle Strand
Además, ¿la extensión realmente cuenta como "metadatos"? Es solo parte del nombre del archivo.
Kyle Strand
1
Los metadatos de un archivo incluyen el nombre de archivo completo, el tiempo de creación, los bits de acceso, etc. Solo el contenido en sí es datos en lugar de metadatos. En cuanto a los "intérpretes múltiples", ese es realmente un problema real y exactamente por qué no debería estar en la línea shebang. ¿Qué pasa si tienes /usr/bin/i686/pythony /usr/bin/amd64/python? Perfectamente razonable, pero rompe los scripts de Python que tienen una suposición codificada /usr/bin/python. La elección del intérprete no es una elección del guionista, sino del usuario del guión. El guionista solo puede elegir el idioma (dialecto).
MSalters
1
@MSalters Bueno, para eso /usr/bin/enves, junto con los scripts env-setup. ¿Cuál es la versión de Windows de esto? ¿Ejecutar un regeditscript justo antes de iniciar un .pyarchivo para asegurarse de obtener el intérprete que desea?
Kyle Strand
41

La línea que ha indicado se usa para indicarle a la computadora qué programa / intérprete usar cuando ejecuta el archivo / script directamente, y cualquier argumento que deba pasarse a ese programa cuando se ejecute el script. Sin embargo, esto no es un requisito de Python , es un requisito del kernel / sistema de Linux si tiene la intención de ejecutar el script directamente (y no pasarlo a Python por la sintaxis a continuación).

No es necesario si va a ejecutar python script.pyo similar. Solo es necesario si tiene la intención de ejecutar el script / archivo directamente, sin proporcionar también el intérprete para usar (como python).


Para un script Bash, tendría algo como esto:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

Esto indicaría al sistema que, cuando esto se ejecuta, debe ejecutarse a través de /bin/bashuno de los idiomas shells / shell-script en el sistema.


Sin embargo, para el código de Python, aquí querrá que el archivo ejecutable se ejecute a través de Python, por lo que le dirá qué intérprete pretende ejecutar.

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

Esto, al igual que para Bash, indica que /usr/bin/pythondebe usarse (probablemente Python 2 o Python 3, dependiendo de las configuraciones individuales de su sistema).


De esta manera, se puede ejecutar ./filename.pyo ./executableo ./scripttorundirectamente.

Sin esa línea al principio, y suponiendo que haya configurado el archivo / script para que sea ejecutable, y suponiendo que esté trabajando con un script de Python, tendría que ejecutar python filename.pyo similar si no tuviera la #!/usr/bin/pythonlínea. (Para una secuencia de comandos Bash, tendría que hacer bash script.sho similar para otras secuencias de comandos / idiomas, como Perl, Ruby, etc.)

El resaltado de sintaxis anterior es específico del idioma en cada sección, aunque en realidad no importa.

Thomas Ward
fuente
1
Una cosa interesante a añadir sería que es posible especificar parámetros adicionales después de que el propio tinglado, en la mayoría de los casos en la misma forma que si el intérprete se llama directa ( #!/bin/bash -x, #!/usr/bin/perl -lan, etc.).
kos
77
@kos: Creo que puede especificar exactamente un argumento adicional, que ha sido un PITA cuando uno (debería) usarlo /usr/bin/env pythonpara obtener el pitón correcto.
unperson325680
@progo No estoy seguro de cuál es el problema env, pero parece que el problema no es la cantidad de argumentos: #!/usr/bin/perl -l -a -ntiene tres argumentos pero funciona. Aunque, de nuevo, no puedo entender el problema exacto.
kos
Cuando se llama explícitamente a un intérprete con el guión como argumento, no hay razón para comenzar con este último ./. En otras palabras, solo python filename.pyo bash script.shfuncionará bien. La única razón para incluir ./está en un nombre de comando, cuando desea decirle al shell que no busque $PATH(que probablemente no encontrará archivos en el directorio actual) sino que tome la ruta que especificó tal como está. Pero eso no se aplica a los argumentos de comando.
Marc van Leeuwen
@kos: El problema podría estar en cómo envrecibe el resto de los argumentos del núcleo. Se podría suponer que todos son un gran argumento sin división por espacio. Perdón por la articulación, ya no recuerdo bien los detalles de esto
Unperson325680
16

La línea:

#!/usr/bin/python

se llama 'shebang' e indica la ruta al binario del intérprete que se usará para interpretar el resto de los comandos del archivo. Suele ser la primera línea de un guión.

Entonces la línea #!/usr/bin/pythonindica que el contenido del archivo será interpretado por el pythonbinario ubicado en /usr/bin/python.

Tenga en cuenta que la línea shebang es analizada por el kernel y luego el script eventualmente se llamará como argumento:

python script_name

Del mismo modo en caso de #!/bin/bash:

bash script_name
heemayl
fuente
2
No creo haber visto nunca un guión shebang. Dado que la palabra se forma a partir de "hash" y "bang", su ortografía no es muy clara, ya que parece que es una combinación de "ella" y "bang".
Kyle Strand
Puede llamarlo hashbang( #= "hash") o shebang( #= "sharp"), dependiendo de cómo nombre al #personaje. Sin embargo, de shebanghecho es más común. @KyleStrand
Byte Commander
7

Técnicamente, no lo requiere. Requiere una ruta al entorno donde se ejecuta su script. Sería mejor que sus futuros scripts incluyan / usr / bin / env y luego especifique python. Esto garantiza que su script se ejecute en el entorno de Python, sin importar dónde esté instalado. Desea hacer esto por razones de compatibilidad, no puede estar seguro de que la próxima persona con la que comparta su código tendrá Python instalado en usr / bin / python, o que tendrán permisos para esos archivos del sistema.

Aquí es una Q y similares Una de desbordamiento de pila .

Lo que se ve en su script es:

#!/usr/bin/env python

También veo cierta preocupación sobre cómo especificar python3. Aquí está cómo hacerlo:

#!/usr/bin/env python3
j0h
fuente
5

En Linux, Python puede o no requerir la #!línea (shebang). Esto depende de cómo se manejen los códigos de Python, ya sea ejecutando los códigos en modo interactivo de Python o en un script de Python.

El modo interactivo de Python permite al usuario escribir y ejecutar códigos de Python directamente, lo que no requiere la línea shebang. Para ejecutar el modo interactivo, abra una Terminal y escriba pythonpara Python 2.X o python3para Python 3.X.

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

La secuencia de comandos de Python permite al usuario escribir y guardar los códigos de Python en un archivo de texto sin formato, y luego ejecutar los códigos más tarde. Esto puede o no requerir la línea shebang. Sin embargo, hay dos razones conocidas cuando se requiere la línea shebang para usar el script Python en Linux.

  1. ejecutar códigos Python en una secuencia de comandos ejecutable, es decir, define cómo se deben ejecutar los códigos y qué intérprete;

  2. ejecutar códigos de Python con respecto a una versión específica de Python, es decir, ejecutar códigos que sean compatibles con Python 2.X o Python 3.X solamente

Practica con scripts de Python

A continuación se encuentran la lista y el contenido de los archivos, que he usado para mostrar casos en los que #!se requiere o no la línea (shebang).

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py contiene solo el código fuente.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
  • hello2.py contiene el código fuente y la línea shebang.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
  • hello2e.pycontiene lo mismo hello2.pyy se hizo ejecutable.

  • hello3.pycontiene lo mismo que hello2.py, excepto que está adaptado para ejecutarse con Python 3 cambiando el nombre de la primera línea a #!/usr/bin/env python3.

  • hello3e.pycontiene lo mismo hello3.pyy se hizo ejecutable.

  • hello3m.pycontiene lo mismo hello3.pyy se hizo ejecutable, excepto que se guarda con la Write Unicode BOMopción en el editor de texto, es decir, Mousepad.

Más allá de este punto, al usuario se le presentarán dos métodos para ejecutar los scripts de Python. Ambos métodos se han demostrado como a continuación.

Método 1: ejecutar con el programa Python

A continuación se muestran los comandos y la salida al ejecutar el código fuente con Python 2 y Python 3.

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Ambas versiones de Python pudieron ejecutar el script con éxito. Por lo tanto, la línea shebang no es necesaria cuando se ejecuta el script Python a través de pythono python3comando.

Método 2: ejecutar como script Python

A continuación se muestran los comandos y la salida al ejecutar el código fuente con la línea shebang, que no están adaptados a Python 2 y Python 3, incluidos los casos no ejecutables y ejecutables.

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Los primeros tres scripts han fallado porque estos scripts no son ejecutables, independientemente de que tengan o no la línea shebang (para la prueba de respaldo, vea el ejemplo adicional a continuación). Los dos últimos scripts tienen una línea shebang y son ejecutables.

Aparentemente, un script que se ha hecho ejecutable es esencialmente inútil sin la línea shebang. Por lo tanto, se requiere la línea shebang y el script debe ser ejecutable cuando se ejecutan los códigos Python en un script ejecutable.

Cuando shebang no funciona

En mi ejemplo preparado y probado, la ejecución hello3m.pycomo script ejecutable ha fallado y ha devuelto un error.

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

Esta es una limitación conocida de que shebang no funciona o se vuelve inválido. Cuando un archivo se guarda como BOM de Unicode (marca de orden de bytes), no se ejecutará normalmente como un script ejecutable de Python.

Ejemplo adicional

Este ejemplo adicional se tratará solo como prueba de apoyo. El usuario debe evitar ejecutar este ejemplo, aunque el resultado es inofensivo.

He creado otro archivo llamado hello1e.py, que contiene lo mismo hello1.pyy se hizo ejecutable. La ejecución de este script devolvió un error de sintaxis.

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token `"Hello from Python %s\n"'
./hello1e.py: line 2: `sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

Al ejecutar este script, al principio, el cursor del mouse se cambiará a un signo más y no hará nada en apariencia. El error de sintaxis no se mostrará hasta que haga clic en la ventana Escritorio o Terminal. Luego, este script creará un sysarchivo en el mismo directorio que el script.

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

El sysarchivo ha sido identificado como archivo PostScript, sin extensión de archivo. Este archivo se puede abrir en el visor de documentos, es decir, Evince, y el archivo en realidad contenía una captura de pantalla de la ventana en la que había hecho clic anteriormente. En mi experiencia, el archivo puede ser tan grande como unos pocos megabytes.

Una vez más, se requiere la línea shebang y el script debe ser ejecutable cuando se ejecuta el script Python como un script ejecutable. De lo contrario, el script se comportará mal como se describe anteriormente.

Notas adicionales

El término "hecho ejecutable" o "debe ser ejecutable" se refiere al permiso para ejecutar el script. Esto se realiza ejecutando el chmod +x FILENAMEcomando en la Terminal, o marcando la opción "Permitir que este archivo se ejecute como un programa" o algo similar en la ventana Propiedades , dentro de un administrador de archivos.

Mientras que otras respuestas existentes habían cubierto casi todo, esta respuesta ha tenido un enfoque diferente al usar ejemplos prácticos para explicar el asunto. La sintaxis del código se ha escrito con cuidado, de modo que los ejemplos podrían ejecutarse con Python 2 o Python 3, tal como están.

Los códigos de Python se han adaptado de Usar Python en Windows y Usar Python en plataformas Unix , con un código adicional de una línea del ubicuo "¡Hola, Mundo!" programa.

Todos los códigos y comandos han sido completamente probados y funcionan en el sistema Xubuntu 14.04, que tenía Python 2.7 y Python 3.4 instalados por defecto.

clearkimura
fuente
4

Significa que cuando se ejecuta ese archivo, su computadora sabe ejecutarlo con el programa /usr/bin/python, así es como lo distingue de otro idioma, como bash, donde lo haría #!/bin/bash. Esto es para que simplemente pueda ejecutar:

./[file-to-execute]

Y sabrá con qué archivo ejecutarlo, en lugar de que usted mismo tenga que especificar algo como:

python ./[file-to-execute].py

La #!parte se conoce comúnmente como shebang o crunch bang .

muru
fuente
2
También un hashbang.
Naftuli Kay
1

Si tiene varias versiones de Python instaladas, /usr/bin/envse asegurará de que el intérprete utilizado sea el primero en su entorno $PATH. La alternativa sería codificar algo así #!/usr/bin/python;

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).

Esta regla solo se aplica al sistema basado en UNIX.

orvi
fuente
0

útil para sistemas operativos como Linux, donde Python 2.x sigue siendo el estándar, pero la mayoría de las personas también descargan 3.x.

2.x correría por defecto. Entonces, mi código 3.x, prefijo #! / Usr / bin / env python3 para que 3.x ejecute el código. Incluso puedo especificar hasta la revisión menor (python 3.xyz) si así lo elijo para tener versiones beta o solo versiones un poco más antiguas.

usuario21784
fuente