Bash Shebang para tontos?

36

Tengo algunos scripts de bash que he configurado y que uso principalmente

#!/bin/bash

pero regularmente me encuentro con algunos que parecen

#!/bin/bash -e
#!/bin/bash -x
#!/bin/bash -ex

y así.

¿Alguien puede explicar el significado y los beneficios de estas opciones de shebang y si se aplican a otros shebangs?

coneybeare
fuente
Esas opciones son específicas de Bash (u otro intérprete). Pueden ser los mismos para otros shells (guión y ksh, por ejemplo), pero serían diferentes para otros intérpretes como AWK y Python. Puede usar muchas de las opciones que acepta el intérprete. Las opciones son específicas del intérprete, mientras que el shebang es una característica del núcleo.
Pausado hasta nuevo aviso.

Respuestas:

41

Si un script /path/to/foocomienza con #!/bin/bash, entonces ejecutar /path/to/foo arg1 arg2es equivalente a ejecutar /bin/bash /path/too/foo arg1 arg2. Si la línea shebang es #!/bin/bash -ex, es equivalente a ejecutar /bin/bash -ex /path/too/foo arg1 arg2. Esta característica es administrada por el núcleo.

Tenga en cuenta que solo puede tener un argumento de manera portátil en la línea shebang: algunos unices (como Linux) solo aceptan un argumento, por lo que #!/bin/bash -e -xbash recibiría el argumento de cinco caracteres -e -x(un error de sintaxis) en lugar de dos argumentos -ey -x.

Para el shell Bourne shy los shells derivados como POSIX sh, bash, ksh y zsh:

  • -e significa que si algún comando falla (lo que indica al devolver un estado distinto de cero), el script finalizará de inmediato.
  • -x hace que el shell imprima un seguimiento de ejecución.

Otros programas pueden entender estas opciones pero con diferentes significados.

Gilles 'SO- deja de ser malvado'
fuente
24

Son opciones pasadas para bashver help setmás información, en este caso:

-x  Print commands and their arguments as they are executed.
-e  Exit immediately if a command exits with a non-zero status.
Ciro
fuente
3
+1 Y -exambas
cosas
Es confuso porque parecen opciones de línea de comandos pasadas a Bash.
Caoilte
2
@Caoilte: Y de hecho lo son (de man bash): In addition to the single-character shell options documented in the description of the set builtin command, bash interprets the following options when it is invoked: [...].
cYrus
1
arrgh! ¡Parpadea y te lo perderás! :).
Caoilte
0

Solo me gustaría mencionar una alternativa aún mejor, como en una versión más portátil:

#!/usr/bin/env bash

El ejemplo anterior usa envpara encontrar el bashejecutable, que no siempre está en /bin/bash. Los #!/bin/bashscripts antiguos no funcionan en NixOS , por ejemplo.

Si usa envcomo se demostró anteriormente, no puede proporcionar un argumento como -ea bash(que yo sepa). Pero puedes hacer esto en su lugar:

#!/usr/bin/env bash
set -e
Simon Alling
fuente
2
Hago esto todo el tiempo, pero no diría que es "más portátil"; de hecho, el riesgo de que el usuario ejecute algo completamente diferente (de lo que se puede suponer que incluye un sistema) es mucho mayor. Por ejemplo, Ubuntu todavía envía Bash 4, mientras que un usuario puede elegir ejecutar Bash 5.
slhck
Sí, el envuso no es bueno especialmente para los scripts que ejecutan python porque simplemente no sabe si el valor predeterminado pythones la versión 2 o 3 y eso hace una gran diferencia para los scripts que necesitan una versión específica. Mejor ser explícito que astuto
smac89