2012-01-23 10 views
346

He hecho Bash scripts antes y todos funcionaron bien sin esto al principio. ¿De qué sirve ponerlo? ¿Las cosas serían diferentes?¿Por qué necesita poner #!/Bin/bash al comienzo de un archivo de script?

Además, ¿cómo se pronuncia #? Sé que ! se pronuncia como "bang".

¿Cómo se pronuncia #!?

+5

No es necesario y no debe hacerlo a menos que no tenga otra opción. Use '#!/Bin/sh' mientras pueda y aprenda sobre la diferencia entre un shell (POSIX) y bash. Llegará un día antes de que su currículum crezca demasiado tiempo, cuando se encuentre en un sistema con un shell diferente y aún desee que sus scripts funcionen. – Jens

+26

Se pronuncia "Hash-Bang" o "She-Bang". – Beachhouse

+10

Creo que vale la pena señalar que esto solo se ejecuta si ejecuta el script como un archivo ejecutable. Entonces, si configura el marcador ejecutable y luego escribe './Yourscript.extension', por ejemplo,'./Helloworld.py' o './Helloworld.sh', buscará el intérprete en esa línea superior, lo que haría ser '#!/bin/python' o'! #/bin/bash', mientras que al ejecutar el script como 'python helloworld.py', la primera línea no se observará porque está comentada. Entonces, es una secuencia especial para el shell/kernel. – JFA

Respuesta

306

Es una convención por lo que el shell * nix sabe qué tipo de intérprete ejecutar.

Por ejemplo, sabores anteriores de ATT por defecto en sh (el shell Bourne), mientras que las versiones anteriores de BSD por defecto en CSH (la C shell).

Incluso hoy en día (donde la mayoría de los sistemas corren bash, el "Bourne Again Shell" ), los scripts pueden ser en bash, Python, Perl, Ruby, PHP, etc, etc. Por ejemplo, podría ver #!/bin/perl o #!/bin/perl5 .

PS: El signo de exclamación (!) se le llama cariñosamente "explosión". El símbolo de comentario de shell (#) a veces se llama "hash".

PPS: Recuerde - bajo * nix, asociando un sufijo con un tipo de archivo no es más que una convención , no una "regla" . Un ejecutable puede ser un programa binario, cualquiera de un millón de tipos de script y otras cosas también. De ahí la necesidad de #!/bin/bash.

+1

Me enteré de algo más útil, $ #. ¿Cómo se llama eso? –

+69

El shebang no es una convención * shell *, es interpretado por * kernel * cuando se maneja la llamada de sistema 'execve (2)'; entonces el shebang es una convención * kernel *, no un shell. –

+6

Además, ayuda a algunos editores como Vim a determinar el idioma para resaltar la sintaxis si el archivo no tiene una extensión. Sin el shebang, Vim mostrará un script bash igual que el archivo de texto sin formato. –

13

El sistema operativo toma el shell predeterminado para ejecutar su script de shell. por lo tanto, al mencionar la ruta del shell al comienzo del script, le está pidiendo al sistema operativo que use ese shell en particular. También es útil para portability.

12

Cada distribución tiene un shell por defecto. Bash es el valor predeterminado en la mayoría de los sistemas. Si trabaja en un sistema que tiene un shell predeterminado diferente, es posible que los scripts no funcionen como deberían si se escriben específicamente para Bash.

Bash ha evolucionado a lo largo de los años tomando el código de ksh y sh.

Agregando #!/bin/bash como la primera línea de su script, le dice al sistema operativo que invoque el shell especificado para ejecutar los comandos que siguen en el script.

#! a menudo se conoce como "hash-bang", "she-bang" o "sha-bang".

40

Se llama shebang. En Unix-speak, # se llama sharp (como en la música) o hash (como hashtags en twitter), y! se llama bang. (En realidad, puede hacer referencia a su comando de shell anterior con !!, llamado bang-bang). Entonces cuando se juntan, se obtiene haSH-BANG, o shebang.

La parte después del #! le dice a Unix qué programa usar para ejecutarlo. Si no se especifica, intentará con bash (o sh, o zsh, o cualquiera que sea su variable $ SHELL) pero si está allí, usará ese programa.Además, # es un comentario en la mayoría de los idiomas, por lo que la línea se ignora en la ejecución posterior.

+1

Si ya estoy en bash, ¿comienza otra instancia de bash si lo ve? #!/bin/bash? ¿Qué pasa si ya estoy en bash y lo dejo afuera? Hay alguna diferencia? –

+2

@javascriptninja de cualquier manera comienza un nuevo shell bash. En el caso de bash, realmente no hay ninguna diferencia, siempre y cuando estés usando Bash. El shebang solo importa si (a) necesitas ejecutar algo que no es solo un caparazón, como Python o Perl, o (b) no usas el shell bash (es decir, usas zsh) pero necesitas ejecutar algo que requiere ser ejecutado en bash. – austin1howard

+0

Sin embargo, en mi opinión, es una buena práctica incluir el shebang, solo para que alguien que lea el código sepa lo que está pasando. – austin1howard

8

Se llama shebang. Consiste en un signo de número y un signo de exclamación (#!), Seguido de la ruta completa al intérprete como/bin/bash. Todos los scripts bajo UNIX y Linux se ejecutan usando el intérprete especificado en una primera línea.

15

El shebang es una directiva para que el cargador utilice el programa que se especifica después del #! como el intérprete del archivo en cuestión cuando intenta ejecutarlo. Por lo tanto, si intenta ejecutar un archivo llamado foo.sh que tiene #!/bin/bash en la parte superior, el comando real que se ejecuta es /bin/bash foo.sh. Esta es una forma flexible de utilizar diferentes intérpretes para diferentes programas. Esto es algo implementado a nivel de sistema y la API de nivel de usuario es la convención shebang.

También vale la pena saber que el shebang es un magic number - uno legible por humanos que identifica el archivo como un script para el intérprete dado.

Su punto de que "funciona" incluso sin el shebang es solo porque el programa en cuestión es un script de shell escrito para el mismo shell que el que está usando. Por ejemplo, podría escribir un archivo javascript y luego poner un #! /usr/bin/js (o algo similar) para tener un "script de Shell" de javascript.

106

Para ser más precisos el shebang#!, cuando son los dos primeros bytes de un archivo ejecutable (xmode), se interpreta por la llamada execve(2) sistema (que ejecutar programas). Pero POSIX specification for execve no menciona el shebang.

Debe ir seguido de una ruta de archivo de un ejecutable de intérprete (que por cierto podría ser relativo, pero la mayoría de las veces es absoluta).

Un buen truco (o tal vez not so nice uno) para encontrar un intérprete (por ejemplo python) en el usuario de $PATH es utilizar el programa env (siempre a /usr/bin/env sobre todo Linux), como por ejemplo,

#!/usr/bin/env python 

Cualquier ejecutable ELF puede ser un intérprete. ¡Incluso podría usar #!/bin/cat o #!/bin/true si quisiera! (pero eso a menudo sería inútil)

+8

Ver [esta pregunta] (http://unix.stackexchange.com/q/29608/10454) para una discusión sobre el pirateo '#!/Usr/bin/env'. –

+0

si quiero pasar un argumento a Python, ¿cómo hago eso? en realidad quiero ejecutar '#!/Usr/bin/env bash -x'. Cómo puedo hacer eso ? – nepsdotin

+0

es simple yo mismo lo encontré, simplemente agregue el parámetro después de eso '#!/Usr/bin/env bash -x' – nepsdotin

0

Puede ser útil para alguien que usa un sistema diferente que no tiene esa biblioteca disponible. Si eso no está declarado y usted tiene algunas funciones en su script que no son compatibles con ese sistema, debe declarar #/bin/bash. Me encontré con este problema antes de trabajar y ahora solo lo incluyo como práctica.

Cuestiones relacionadas