Scripts de depuración, ¿cuál es la diferencia entre -x para establecer -euxo pipefail?

17

La principal forma en que sé depurar scripts es agregar -xshabang ( #!/bin/bash -x).

Recientemente me encontré con una nueva forma, agregando set -euxo pipefailjusto debajo del shabang, como en:

#!/bin/bash
set -euxo pipefail

¿Cuál es la principal diferencia entre las dos formas de depuración? ¿Hay momentos en que preferirías uno sobre el otro?

Como estudiante de primer año, después de leer aquí , no pude extraer tal conclusión.

JohnDoea
fuente

Respuestas:

15

Primero, me temo que la explicación de la -oopción ofrecida por http://explainshell.com no es del todo correcta.

Dado que setes un comando integrado, podemos ver su documentación helpejecutando help set:

  -o option-name
      Set the variable corresponding to option-name:
          allexport    same as -a
          braceexpand  same as -B
          emacs        use an emacs-style line editing interface
          errexit      same as -e
          errtrace     same as -E
          functrace    same as -T
          hashall      same as -h
          histexpand   same as -H
          history      enable command history
          ignoreeof    the shell will not exit upon reading EOF
          interactive-comments
                       allow comments to appear in interactive commands
          keyword      same as -k
          monitor      same as -m
          noclobber    same as -C
          noexec       same as -n
          noglob       same as -f
          nolog        currently accepted but ignored
          notify       same as -b
          nounset      same as -u
          onecmd       same as -t
          physical     same as -P
          pipefail     the return value of a pipeline is the status of
                       the last command to exit with a non-zero status,
                       or zero if no command exited with a non-zero status
          posix        change the behavior of bash where the default
                       operation differs from the Posix standard to
                       match the standard
          privileged   same as -p
          verbose      same as -v
          vi           use a vi-style line editing interface
          xtrace       same as -x

Como puedes ver -o pipefailsignifica:

el valor de retorno de una tubería es el estado del último comando que salió con un estado distinto de cero, o cero si ningún comando salió con un estado distinto de cero

Pero no dice: Write the current settings of the options to standard output in an unspecified format.

Ahora, -xse utiliza para la depuración como ya lo conoce y -edejará de ejecutarse después del primer error en el script. Considere un guión como este:

#!/usr/bin/env bash

set -euxo pipefail
echo hi
non-existent-command
echo bye

La echo byelínea nunca se ejecutará cuando -ese usa porque non-existent-commandno devuelve 0:

+ echo hi
hi
+ non-existent-command
./setx.sh: line 5: non-existent-command: command not found

Sin -ela última línea se imprimiría porque a pesar de que ocurrió un error, no le indicamos que Bashsalga automáticamente:

+ echo hi
hi
+ non-existent-command
./setx.sh: line 5: non-existent-command: command not found
+ echo bye
bye

set -e a menudo se coloca en la parte superior de la secuencia de comandos para asegurarse de que la secuencia de comandos se detendrá cuando se encuentre el primer error; por ejemplo, si la descarga de un archivo falló, no tiene sentido extraerlo.

Arkadiusz Drabczyk
fuente
Leí la respuesta, pero no estoy seguro de entender esto: ¿Cuál es la sintaxis que recomienda usar (creo que es un poco diferente, como esta set -uxo pipefail).
JohnDoea
Si quiere decir set -eque solo causará, causará que el script finalice en caso de error. En su ejemplo, es solo una de las muchas opciones junto con -uxo pipefail.
Arkadiusz Drabczyk
Quise decir que no estoy seguro si me sugieres que use o no el eargumento.
JohnDoea
1
Depende de tus requerimientos. No está configurado de manera predeterminada, por lo que depende del autor. Si está seguro de que todos los comandos utilizados en el script siempre regresarían 0con éxito y no cero en caso de error, entonces -ees útil, pero como todo lo demás, debe usarse con precaución.
Arkadiusz Drabczyk
1
¿Puede ampliar la respuesta y explicar por qué se recomienda -u en este contexto?
Patrice M.