En bash
o sh
, supongo que todo lo que comienza #
es un comentario .
Pero en los bash
guiones escribimos:
#!/bin/bash
Y en los scripts de Python, hay:
#!/bin/python
¿Esto significa que #
por sí mismo es un comentario mientras #!
que no lo es?
#include
. Allí también, el#
no se entiende como un comentario.Respuestas:
La
#!
línea se usa antes de ejecutar el script, luego se ignora cuando se ejecuta el script.Estás preguntando cuál es la diferencia entre una línea shebang y un comentario ordinario.
Una línea que comienza
#!
es tanto un comentario como cualquier otra línea que comienza con#
. Esto es cierto si#!
es la primera línea del archivo o en cualquier otro lugar.#!/bin/sh
tiene un efecto , pero el intérprete no lo lee .#
no es un comentario en todos los lenguajes de programación, pero, como saben, es un comentario en los shells de estilo Bourne que incluyensh
ybash
(así como la mayoría de los shells que no son de estilo Bourne, comocsh
). También es un comentario en Python . Y es un comentario en una variedad de archivos de configuración que en realidad no son scripts (como/etc/fstab
).Supongamos que un script de shell comienza con
#!/bin/sh
. Ese es un comentario, y el intérprete (el shell) ignora todo en la línea después del#
personaje.El propósito de una
#!
línea no es proporcionar información al intérprete. El propósito de la#!
línea es decirle al sistema operativo (o cualquier proceso que inicie el intérprete) qué usar como intérprete .Si invoca el script como un archivo ejecutable, por ejemplo, al ejecutar
./script.sh
, el sistema consulta la primera línea para ver si comienza con#!
, seguido de cero o más espacios, seguido de un comando. Si lo hace, ejecuta ese comando con el nombre del script como argumento. En este ejemplo, se ejecuta/bin/sh script.sh
(o, técnicamente/bin/sh ./script.sh
).Si invoca el script llamando explícitamente al intérprete, la
#!
línea nunca se consulta. Entonces, si corressh script.sh
, la primera línea no tiene efecto. Siscript2.sh
la primera línea es#!/usr/games/nibbles
, la ejecuciónsh script2.sh
no intentará abrir el script ennibbles
(pero lo./script2.sh
hará).Notarás que en ninguno de los casos la extensión del script (
.sh
), si tiene una, afecta la forma en que se ejecuta. En un sistema tipo Unix, esto normalmente no afecta la forma en que se ejecuta el script. En algunos otros sistemas, como Windows, el sistema#!
puede ignorar por completo la línea shebang, y la extensión puede determinar qué ejecuta los scripts. (Esto no significa que necesite dar extensiones a sus scripts, pero es una de las razones por las que si lo hace, deberían ser correctas).#!
fue elegido para cumplir este propósito precisamente porque#
comienza un comentario. La#!
línea es para el sistema, no para el intérprete, y debe ser ignorada por el intérprete.Línea Shebang para secuencias de comandos Bash
Usted (originalmente) dijo que usaba
#!/bin/sh
para losbash
scripts. Solo debe hacer eso si la secuencia de comandos no requiere ninguna debash
las extensiones:sh
necesita poder ejecutar la secuencia de comandos.sh
no siempre es un enlace simbólico abash
. A menudo, incluso en todos los sistemas Debian y Ubuntu remotos recientes ,sh
es un enlace simbólico adash
.Línea Shebang para scripts Python
También dijo (en la primera versión de su pregunta, antes de editar) que comienza con sus scripts Python
#!/bin/sh read by the interpretor
. Si lo dices literalmente, entonces definitivamente deberías dejar de hacerlo. Sihello.py
comienza con esa línea, la ejecución se./hello.py
ejecuta:/bin/sh
intentará ejecutar un script llamadoread
(conby the interpretor hello.py
sus argumentos),read
(con suerte) no será encontrado, y su script Python nunca será visto por un intérprete de Python.Si está cometiendo este error pero no tiene el problema que estoy describiendo, probablemente esté invocando sus scripts de Python especificando explícitamente el intérprete (por ejemplo,
python hello.py
), haciendo que se ignore la primera línea. Cuando distribuye sus scripts a otros, o los usa mucho tiempo después, puede que no esté claro que esto sea necesario para que funcionen. Es mejor arreglarlos ahora. O al menos elimine la primera línea por completo, de modo que cuando no se ejecuten con./
el mensaje de error tenga sentido.Para los scripts de Python, si sabe dónde está (o va a estar) el intérprete de Python, puede escribir la
#!
línea de la misma manera:O, si se trata de un script de Python 3, debe especificar
python3
, yapython
que casi siempre es Python 2 :Sin embargo, el problema es que si bien
/bin/sh
se supone que siempre existe, y/bin/bash
casi siempre existe en los sistemas quebash
vienen con el sistema operativo, Python puede existir en una variedad de lugares.Por lo tanto, muchos programadores de Python usan esto en su lugar:
(O
#!/usr/bin/env python3
para Python 3.)Esto hace que el script se base en
env
estar en el "lugar correcto" en lugar de confiar enpython
estar en el lugar correcto. Eso es bueno porque:env
casi siempre se encuentra en/usr/bin
.python
debe ejecutar la secuencia de comandos es la que aparece por primera vez en elPATH
. Comenzandohello.py
con#!/usr/bin/env python
make./hello.py
run/usr/bin/env python hello.py
, que es (virtualmente) equivalente a correrpython hello.py
.La razón por la que no puede usar
#!python
es que:/
)python
en el directorio actual . Buscar la ruta cuando el comando no contiene una barra oblicua es un comportamiento de shell específico.Ocasionalmente, un Python u otro script que no sea un script de shell tendrá una línea shebang que comienza
#!/bin/sh ...
donde...
hay algún otro código. Esto a veces es correcto, porque hay algunas formas de invocar el shell compatible con Bourne (sh
) con argumentos para que invoque un intérprete de Python. (Uno de los argumentos probablemente contendrápython
). Sin embargo, para la mayoría de los propósitos,#!/usr/bin/env python
es más simple, más elegante y es más probable que funcione de la manera que desee.Shebang Lines en otros idiomas
Muchos lenguajes de programación y secuencias de comandos, y algunos otros formatos de archivo, se usan
#
como comentario. Para cualquiera de ellos, un archivo en el lenguaje puede ser ejecutado por un programa que lo toma como argumento especificando el programa en la primera línea después#!
.En algunos lenguajes de programación,
#
normalmente no es un comentario, pero como caso especial se ignora la primera línea si comienza con#!
. Esto facilita el uso de la#!
sintaxis aunque de#
otra manera no hace que una línea sea un comentario.Líneas Shebang para archivos que no se ejecutan como scripts
Si bien es menos intuitivo, cualquier archivo cuyo formato de archivo puede acomodar una primera línea que comienza con
#!
seguido de la ruta completa de un ejecutable puede tener una línea shebang. Si hace esto, y el archivo está marcado como ejecutable, puede ejecutarlo como un programa ... haciendo que se abra como un documento.Algunas aplicaciones usan este comportamiento intencionalmente. Por ejemplo, en VMware, los
.vmx
archivos definen máquinas virtuales. Puede "ejecutar" una máquina virtual como si fuera un script porque estos archivos están marcados como ejecutables y tienen una línea shebang que hace que se abran en una utilidad VMware.Shebang Lines para archivos que no se ejecutan como scripts pero que, de todos modos, actúan como scripts
rm
elimina archivos No es un lenguaje de script. Sin embargo,#!/bin/rm
se puede ejecutar un archivo que se inicia y está marcado como ejecutable, y cuando lo ejecuta,rm
se invoca y lo elimina.Esto a menudo se conceptualiza como "el archivo se elimina a sí mismo". Pero el archivo no se está ejecutando en absoluto. Esto se parece más a la situación descrita anteriormente para los
.vmx
archivos.Aún así, debido a que la
#!
línea facilita la ejecución de un comando simple (incluidos los argumentos de la línea de comandos), puede realizar algunas secuencias de comandos de esta manera. Como un ejemplo simple de un "script" más sofisticado que#!/bin/rm
, considere:Esto toma la entrada del usuario de forma interactiva, la devuelve eco al usuario línea por línea y la agrega al final del archivo "script".
¿Útil? No muy. ¿Conceptualmente interesante? ¡Totalmente! Si. (Algo.)
Conceptos de programación / scripting conceptualmente similares (solo por diversión)
Scripts / programas que son múltiples idiomas a la vez , por ejemplo, para simular la funcionalidad hashbang en sistemas operativos que no lo tenían .
(Estos programas se denominan políglotas , pero esto no debe confundirse con el otro sentido de políglota en el desarrollo de software , un programa / proyecto donde se escriben diferentes partes en diferentes idiomas).
Los metacomandos en QBasic / QuickBASIC, que señalaron al compilador (para el código compilado) opciones para la generación de código, pero fueron parte de los comentarios y, por lo tanto, se ignoraron durante la compilación / interpretación real.
fuente
-x
bandera de Pythons ?-x
"omitir [s] la primera línea ..." la segunda línea se numera en1
lugar de2
la tercera línea en2
lugar de3
, etc. Es por eso que no debes usar esa bandera. ;)-x
es para crear scripts en sistemas operativos que no son de Unix que tienen una sintaxis similar a shebang que no comienza#
(por lo tanto, no es un comentario de Python).perl script.pl
vs./script.pl
), entonces el intérprete se lee la línea tinglado para analizar banderas tales como-w
. Sin embargo, no se recomienda confiar en esta característica.Un shebang es la secuencia de caracteres que consiste en el signo de número de caracteres y el signo de exclamación (por ejemplo, "#!") Cuando aparece como los dos caracteres iniciales en la línea inicial de un guión.
En los sistemas operativos * nix, cuando se ejecuta un script que comienza con un shebang, el cargador de programas analiza el resto de la línea inicial del script como una directiva de intérprete; en su lugar, se ejecuta el programa de intérprete especificado, pasándole como argumento la ruta que se usó inicialmente al intentar ejecutar el script. Por ejemplo, si un script se nombra con la ruta "path / to / your-script", y comienza con la siguiente línea:
luego se le indica al cargador del programa que ejecute el programa "/ bin / sh", por ejemplo, el shell Bourne o un shell compatible, pasando "path / to / your-script" como primer argumento.
En consecuencia, se llama un script con la ruta "path / to / python-script" y comienza con la siguiente línea:
entonces el programa cargado recibe instrucciones de ejecutar el programa "/ bin / python", por ejemplo, intérprete de Python, pasando "path / to / python-script" como primer argumento.
En resumen "#" comentará una línea mientras que la secuencia de caracteres "#!" que ocurre como los dos primeros caracteres en la línea inicial de un guión tiene un significado descrito como anteriormente.
Para obtener detalles, consulte ¿Por qué algunos scripts comienzan con #! ...?
Fuente: Algunas secciones de esta respuesta se derivan (con una ligera modificación) de Shebang (Unix) en Wikipedia en inglés (por colaboradores de Wikipedia ). Este artículo está licenciado bajo CC-BY-SA 3.0 , igual que el contenido del usuario aquí en AU, por lo que esta derivación está permitida con atribución.
fuente
#!
se llamashebang
cuando ocurre como los dos caracteres iniciales en la línea inicial de un script. Se usa en scripts para indicar un intérprete para la ejecución. Elshebang
es para el sistema operativo (kernel), no para el shell; así que no se interpretará como un comentario.Cortesía: http://en.wikipedia.org/wiki/Shebang_%28Unix%29
Información detallada: http://wiki.bash-hackers.org/scripting/basics#the_shebang
fuente
No, solo lo usa la
exec
llamada al sistema del kernel de Linux y el intérprete lo trata como un comentario.Cuando 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, entonces la
exec
llamada al sistema usaría un controlador diferente. El otro controlador integrado 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 núcleo ve esos bytes, toma el archivo ELF, lo guarda en la memoria correctamente y comienza un nuevo proceso con él. Ver también: https://stackoverflow.com/questions/8352535/how-does-kernel-get-an-executable-binary-file-running-under-linux/31394861#31394861
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 ocurrir".
fuente