Was ist der Unterschied zwischen -x und -euxo pipefail beim Debuggen von Skripten?

17

Die Hauptmethode zum Debuggen von Skripten ist das Hinzufügen -xvon shabang ( #!/bin/bash -x).

Ich bin kürzlich auf einen neuen Weg set -euxo pipefailgestoßen, indem ich direkt unter dem Shabang hinzugefügt habe, wie in:

#!/bin/bash
set -euxo pipefail

Was ist der Hauptunterschied zwischen den beiden Möglichkeiten des Debuggens? Gibt es Zeiten, in denen Sie es vorziehen würden?

Als Neuling, nachdem ich hier gelesen hatte , konnte ich solche Schlussfolgerungen nicht ziehen.

JohnDoea
quelle

Antworten:

15

Erstens befürchte ich, dass diese Erklärung der -oOption von http://explainshell.com bereitgestellt wird wird, nicht ganz korrekt ist.

Da dies setein integrierter Befehl ist, können wir seine Dokumentation anzeigen, helpindem wir Folgendes ausführen 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

Wie Sie sehen können, -o pipefailbedeutet dies:

Der Rückgabewert einer Pipeline ist der Status des letzten Befehls, der mit einem Status ungleich Null beendet wurde, oder Null, wenn kein Befehl mit einem Status ungleich Null beendet wurde

Aber es heißt nicht: Write the current settings of the options to standard output in an unspecified format.

Wird jetzt -xzum Debuggen verwendet, wie Sie es bereits kennen, und -ewird nach dem ersten Fehler im Skript nicht mehr ausgeführt. Betrachten Sie ein Skript wie dieses:

#!/usr/bin/env bash

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

Die echo byeZeile wird niemals ausgeführt, wenn sie verwendet -ewird, da non-existent-commandkeine 0 zurückgegeben wird:

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

Ohne -edie letzte Zeile würde gedruckt werden, da wir trotz eines Fehlers nicht angewiesen haben Bash, automatisch zu beenden:

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

set -e wird häufig am Anfang des Skripts platziert, um sicherzustellen, dass das Skript angehalten wird, wenn der erste Fehler auftritt. Wenn beispielsweise das Herunterladen einer Datei fehlgeschlagen ist, ist es nicht sinnvoll, sie zu extrahieren.

Arkadiusz Drabczyk
quelle
Ich lese die Antwort , aber ich bin nicht sicher , ob diese erhalte ich: Was ist die Syntax , die Sie empfehlen (ich glaube , es ist etwas anders, wie diese set -uxo pipefail).
JohnDoea
Wenn Sie meinen, set -ees würde nur dazu führen, dass das Skript bei einem Fehler beendet wird. In Ihrem Beispiel ist es nur eine von vielen Optionen zusammen mit -uxo pipefail.
Arkadiusz Drabczyk
Ich wollte damit sagen, dass ich nicht sicher bin, ob Sie mir vorschlagen, das eArgument zu verwenden oder nicht .
JohnDoea
1
Das hängt von Ihren Anforderungen ab. Es ist nicht standardmäßig festgelegt, so dass es dem Autor überlassen bleibt. Wenn Sie sicher sind, dass alle Befehle, die im Skript verwendet werden, bei 0Erfolg immer zurückkehren und bei Fehlern ungleich Null sind, -eist dies nützlich, aber wie alles andere sollte es mit Vorsicht verwendet werden.
Arkadiusz Drabczyk
1
Können Sie vielleicht die Antwort erweitern und erklären, warum -u in diesem Zusammenhang empfohlen wird?
Patrice M.