Comment restaurer correctement les paramètres lors de l'exécution d'un script en utilisant «source»?

9

J'écris un script qui doit être exécuté en utilisant source, car sa tâche est de modifier l'environnement. Pendant le script, je veux l'utiliser set -epour que toute erreur arrête le script. Le script ressemble à ceci:

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

Le problème est que, set -enaturellement, reste en vigueur après la fin du script. Comment puis-je m'assurer que l' setoption modifiée est correctement restaurée à sa valeur précédente lorsque le script s'arrête (de quelque manière que ce soit - en réussissant ou en cas d'erreur)?

Petr Pudlák
la source
stackoverflow.com/questions/29528624/…
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
Le même problème (pour l' option -x/ xtrace) est résolu à Supprimer la trace d'exécution pour la commande echo?
Scott

Réponses:

3

Exactement de la même manière que vous l'activez: appeler le buitin set:

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

Depuis la bash(1)page de manuel, sous la SHELL BUILTIN COMMANDSsection, commande `set ':

-o option-name
The option-name can be one of the following:
    errexit Same as -e.
dawud
la source
3
Existe-t-il un moyen de sauvegarder (tous) ces paramètres et de les restaurer plus tard?
Petr Pudlák
Exécutez set -opour connaître votre configuration actuelle. Soyez explicite lorsque vous définissez / supprimez l'un d'eux sur vos scripts.
dawud
12

La commande set +orépertorie les paramètres actuels comme des commandes qui restaurent le même état, par exemple

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

Vous pouvez facilement restaurer toutes les options plus tard, si vous enregistrez cette sortie dans une variable shell:

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

Bash comprend également un certain nombre d'options non standard (pas POSIX) qui sont ajustées à l'aide de la shoptcommande. La commande shopt -ppeut être utilisée pour enregistrer ces options d'une manière similaire.

Si vous ne souhaitez enregistrer et restaurer qu'une seule option, vous pouvez utiliser la variable d'environnement $ -, qui répertorie l'ensemble d'options actuel sous forme de lettres, par exemple

$ echo $-
himBH

Vous pouvez utiliser quelque chose comme ceci pour enregistrer et restaurer une option particulière:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e
Seppo Enarvi
la source
Notez qu'il est très important de ne pas manquer les guillemets autour de "$ SAVED_OPTIONS" dans l'appel eval.
Matt
3

Utilisez un piège RETOUR

RETURN les pièges fonctionnent également pour les scripts d'origine.

Les commandes spécifiées avec un RETURNtrap sont exécutées avant la reprise de l'exécution après une fonction shell ou un script shell exécuté avec .ou sourceretourne.

- 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

Tester

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

La restauration des paramètres activés précédents peut être effectuée rapidement comme suit:

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

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

set -$PREV_SETTING

Dans l'autre sens (restauration à l'état désactivé) AFAIK, il n'y a pas un tel raccourci et la réponse de Seppo couvre tous les cas.

F Pereira
la source
Votre code tel qu'écrit donne -bash: set: -i: invalid optionparce que le -idrapeau note un shell interactif.
dpw