Wie kann ich die Einstellungen ordnungsgemäß wiederherstellen, wenn ein Skript mit "source" ausgeführt wird?

9

Ich schreibe ein Skript, das mit ausgeführt werden muss source, da es die Aufgabe hat, die Umgebung zu ändern. Während des Skripts möchte ich verwenden, set -edamit ein Fehler das Skript stoppt. Das Skript sieht folgendermaßen aus:

#!/bin/bash
set -e
# do something
cd somewhere
source anotherScript

Das Problem ist, dass dies set -enatürlich auch nach Abschluss des Skripts wirksam bleibt. Wie kann ich sicherstellen, dass die geänderte setOption beim Beenden des Skripts ordnungsgemäß auf den vorherigen Wert zurückgesetzt wird (auf irgendeine Weise - entweder durch erfolgreichen Abschluss oder aufgrund eines Fehlers)?

Petr Pudlák
quelle
stackoverflow.com/questions/29528624/…
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功
Das gleiche Problem (für die Option -x/ xtrace) wird unter Ausführungsablaufverfolgung für Echobefehl unterdrücken behoben.
Scott

Antworten:

3

Genau so, wie Sie es aktivieren: Rufen Sie das Buitin auf set:

$ set -o errexit
$ set -o | grep errexit
errexit         on
$ set +o errexit
$ set -o | grep errexit
errexit         off

In der bash(1)Manpage unter dem SHELL BUILTIN COMMANDSAbschnitt "set" Befehl:

-o option-name
The option-name can be one of the following:
    errexit Same as -e.
dawud
quelle
3
Gibt es eine Möglichkeit, (alle) Einstellungen zu speichern und später wiederherzustellen?
Petr Pudlák
Führen set -oSie das aktuelle Setup aus. Seien Sie explizit, wenn Sie eines davon in Ihren Skripten setzen / deaktivieren.
Dawud
12

Der Befehl set +olistet die aktuellen Einstellungen als Befehle auf, die denselben Status wiederherstellen, z

$ set +o
set +o allexport
set -o braceexpand
set -o emacs
set +o errexit
set +o errtrace
...

Sie können alle Optionen später problemlos wiederherstellen, wenn Sie diese Ausgabe in einer Shell-Variablen speichern:

SAVED_OPTIONS=$(set +o)
set -e
# do something
eval "$SAVED_OPTIONS"

Bash enthält auch eine Reihe von nicht standardmäßigen (nicht POSIX) Optionen, die mit dem shoptBefehl angepasst werden . Mit dem Befehl shopt -pkönnen diese Optionen auf ähnliche Weise gespeichert werden.

Wenn Sie nur eine Option speichern und wiederherstellen möchten, können Sie die Umgebungsvariable $ - verwenden, in der die aktuellen Optionen als Buchstaben aufgeführt sind, z

$ echo $-
himBH

Sie können so etwas verwenden, um eine bestimmte Option zu speichern und wiederherzustellen:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e
Seppo Enarvi
quelle
Beachten Sie, dass es sehr wichtig ist, die Anführungszeichen um "$ SAVED_OPTIONS" im eval-Aufruf nicht zu verpassen.
Matt
3

Verwenden Sie eine RETURN-Falle

RETURN Traps funktionieren auch für Skripts.

Mit einem RETURNTrap angegebene Befehle werden ausgeführt, bevor die Ausführung fortgesetzt wird, nachdem eine Shell-Funktion oder ein Shell-Skript mit ausgeführt .oder sourcezurückgegeben wurde.

- https://www.gnu.org/software/bash/manual/bash.html

main_script.sh

#!/usr/bin/env bash
echo "inside main script"
shopt -o errexit
source a_script_to_be_sourced.sh
echo "back inside main script"
shopt -o errexit

a_script_to_be_sourced.sh

trap "$(shopt -p -o errexit)" RETURN
set -e # Equivalents: set -o errexit; shopt -s -o errexit
echo "inside sourced script"
shopt -o errexit

Prüfung

$ ./main_script.sh 
inside main script
errexit         off
inside sourced script
errexit         on
back inside main script
errexit         off
Robin A. Meade
quelle
2

Das Wiederherstellen zuvor aktivierter Einstellungen kann schnell erfolgen als:

PREV_SETTING=$-  # e.g. himxBH  (there was xtrace)

set +x
# do your script without xtrace, ...

set -$PREV_SETTING

Umgekehrt (Wiederherstellung in den ausgeschalteten Zustand) AFAIK gibt es keine solche Abkürzung und Seppos Antwort deckt alle Fälle ab.

F Pereira
quelle
Ihr geschriebener Code ergibt, -bash: set: -i: invalid optionweil das -iFlag eine interaktive Shell notiert.
dpw