¿Bash Shebang para tontos?

¿Bash Shebang para tontos?

Tengo algunos scripts de bash que configuré y que uso principalmente

#!/bin/bash

pero regularmente me encuentro con algunos que se parecen

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

etcétera.

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

Respuesta1

Si un script /path/to/foocomienza con #!/bin/bash, 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, equivale a ejecutar /bin/bash -ex /path/too/foo arg1 arg2. Esta característica es administrada por el kernel.

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

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

  • -esignifica que si algún comando falla (lo que indica al devolver un estado distinto de cero), el script finalizará inmediatamente.
  • -xhace que el shell imprima un seguimiento de ejecución.

Otros programas pueden entender estas opciones pero con significados diferentes.

Respuesta2

Son opciones pasadas a bashver help setpara más info, 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.

Respuesta3

Sólo me gustaría mencionar una alternativa aún mejor, más portátil:

#!/usr/bin/env bash

El ejemplo anterior se utiliza envpara buscar el bashejecutable, que no siempre está en /bin/bash. Los scripts antiguos #!/bin/bashno funcionanNixOS, Por ejemplo.

Si usa envcomo se demostró anteriormente, no puede proporcionar un argumento como -eto bash(hasta donde yo sé). Pero puedes hacer esto en su lugar:

#!/usr/bin/env bash
set -e

Respuesta4

Iniciar un script con , o ejecutar de manera equivalente , tiene el mismo efecto que insertar dentro del script justo después de su línea.#! /path/to/bash -optionbash -option /path/to/scriptset -option#!

set -xes esencialmente sólo para depurar; No querrás que lo dejes encendido normalmente.

El efecto de set -ees mucho más complicado de lo que sugiere el manual. La descripción más precisa es aproximadamente:

Después de invocar set -e, si unno probadoEl comando sale con un estado distinto de cero, hará que el shell salga con ese estado de salida.

yo digomás precisoporque todavía es bastante vaga: la lista de situaciones en las que se considera el comandoprobadoEs arcano y difícil de predecir. Las reglas exactas difieren entre shells e incluso cambian entre versiones del mismo shell.

set -ehacenohacer que Bash salga en respuesta al estado de salida distinto de cero de cualquier comando:

  • ifen medio elify then; o
  • whileen medio untily do; o
  • siguiente !; o
  • seguido de ||o &&o &(aunque para &el correspondiente waito fgpuede fallar); o
  • seguido de |, a menos que set -o pipefailesté vigente; o
  • dentro $( ... )cuando se usa como parte de un comando (no asignaciones y/o redirecciones simples, lo que significa que foo=$( bar )fallará si barfalla, pero local foo=$( bar )no lo hará); o
  • dentro de un comando compuesto donde se aplica lo anterior; o
  • dentro de una función de shell invocada desde cualquier lugar donde se aplique lo anterior.

Los efectos sobre los comandos compuestos y las funciones del shell son recursivos.

Debido a que el propio shell sale con un estado distinto de cero, el efecto puede propagarse fuera de un subshell.

La !exención se aplica incluso si se ignora el estado de salida invertido.

Por el contrario, set -elos desencadenantes deuno sí y otro noestado distinto de cero, independientemente de si significa "fallido" o simplemente "falso". Por ejemplo, ((x++))tendrá un estado de salida "fallido" distinto de cero cuando xinicialmente sea 0.

Debido a que es un desastre, hay una escuela de pensamiento que dice que set -ese debe evitar y se debe verificar explícitamente todos los comandos.

O si aún deseas utilizar set -e, recuerda escribir !delante de cualquier ((arithmetic))grupo.

información relacionada