Debugowanie skryptów, jaka jest różnica między -x, aby ustawić -euxo pipefail?

17

Głównym sposobem, w jaki znam debugowanie skryptów, jest dodanie -xdo shabang ( #!/bin/bash -x).

Ostatnio natknąłem się na nowy sposób, dodając set -euxo pipefailtuż pod shabangiem, jak w:

#!/bin/bash
set -euxo pipefail

Jaka jest główna różnica między dwoma sposobami debugowania? Czy są chwile, kiedy wolisz jeden od drugiego?

Jako student pierwszego roku po przeczytaniu tutaj nie mogłem wyciągnąć takiego wniosku.

JohnDoea
źródło

Odpowiedzi:

15

Po pierwsze, obawiam się, że wyjaśnienie -oopcji obsługiwanej przez http://explainshell.com nie jest całkowicie poprawne.

Biorąc pod uwagę, że setjest to polecenie wbudowane, możemy zobaczyć jego dokumentację help, wykonując 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

Jak widać -o pipefailoznacza:

zwracana wartość potoku jest statusem ostatniego polecenia kończącego się ze statusem niezerowym lub zerowym, jeśli żadne polecenie nie zostało zakończone ze statusem niezerowym

Ale nie mówi: Write the current settings of the options to standard output in an unspecified format.

Teraz -xsłuży do debugowania, jak już go znasz, i -eprzestanie działać po pierwszym błędzie w skrypcie. Rozważmy taki skrypt:

#!/usr/bin/env bash

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

echo byeLinia nigdy nie zostanie wykonane, gdy -ejest używany, ponieważ non-existent-commandnie zwraca 0:

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

Bez -eostatniego wiersza zostałby wydrukowany, ponieważ mimo wystąpienia błędu nie powiedzieliśmy Bashautomatycznego wyjścia:

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

set -e jest często umieszczany u góry skryptu, aby upewnić się, że skrypt zostanie zatrzymany po napotkaniu pierwszego błędu - na przykład, jeśli pobieranie pliku nie powiedzie się, nie ma sensu go rozpakowywać.

Arkadiusz Drabczyk
źródło
Przeczytałem odpowiedź, ale nie jestem pewien, czy ją otrzymałem: Jakiej składni polecasz użyć (sądzę, że jest nieco inna, taka jak ta set -uxo pipefail).
JohnDoea,
Jeśli masz na myśli, set -eże to tylko spowoduje, że skrypt zakończy działanie po błędzie. W twoim przykładzie jest to tylko jedna z wielu opcji razem z -uxo pipefail.
Arkadiusz Drabczyk
Chciałem powiedzieć, że nie jestem pewien, czy sugerujesz mi użycie eargumentu, czy nie .
JohnDoea,
1
To zależy od twoich wymagań. To nie jest ustawione domyślnie, więc to zależy od autora. Jeśli masz pewność, że wszystkie polecenia użyte w skrypcie zawsze powrócą 0w przypadku sukcesu, a niezerowe w przypadku niepowodzenia, to -ejest przydatne, ale podobnie jak wszystko inne, należy używać go ostrożnie.
Arkadiusz Drabczyk
1
Czy możesz rozszerzyć odpowiedź, wyjaśniając, dlaczego -u jest zalecane w tym kontekście?
Patrice M.