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/foo
comienza con #!/bin/bash
, ejecutar /path/to/foo arg1 arg2
es 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 -x
bash recibiría un único argumento de cinco caracteres -e -x
(un error de sintaxis) en lugar de dos argumentos -e
y -x
.
Para el shell Bourne sh
y 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á inmediatamente.-x
hace que el shell imprima un seguimiento de ejecución.
Otros programas pueden entender estas opciones pero con significados diferentes.
Respuesta2
Son opciones pasadas a bash
ver help set
para 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 env
para buscar el bash
ejecutable, que no siempre está en /bin/bash
. Los scripts antiguos #!/bin/bash
no funcionanNixOS, Por ejemplo.
Si usa env
como se demostró anteriormente, no puede proporcionar un argumento como -e
to 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 -option
bash -option /path/to/script
set -option
#!
set -x
es esencialmente sólo para depurar; No querrás que lo dejes encendido normalmente.
El efecto de set -e
es 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 -e
hacenohacer que Bash salga en respuesta al estado de salida distinto de cero de cualquier comando:
if
en medioelif
ythen
; owhile
en mediountil
ydo
; o- siguiente
!
; o - seguido de
||
o&&
o&
(aunque para&
el correspondientewait
ofg
puede fallar); o - seguido de
|
, a menos queset -o pipefail
esté vigente; o - dentro
$( ... )
cuando se usa como parte de un comando (no asignaciones y/o redirecciones simples, lo que significa quefoo=$( bar )
fallará sibar
falla, perolocal 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 -e
los 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 x
inicialmente sea 0.
Debido a que es un desastre, hay una escuela de pensamiento que dice que set -e
se 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.