Come ripristinare correttamente le impostazioni quando si esegue uno script usando "source"?


9

Sto scrivendo uno script che deve essere eseguito utilizzando source, perché il suo compito è modificare l'ambiente. Durante lo script, voglio usare in set -emodo che qualsiasi errore interrompa lo script. Lo script è simile al seguente:

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

Il problema è che set -erimane naturalmente in vigore al termine dello script. Come posso garantire che l' setopzione modificata venga ripristinata correttamente al suo valore precedente quando lo script si arresta (in qualsiasi modo, completandolo correttamente o in caso di errore)?



Lo stesso problema (per l' opzione -x/ xtrace) è stato risolto in Sopprimi traccia esecuzione per comando echo?
Scott,

Risposte:


3

Esattamente allo stesso modo in cui lo attivi: chiamando il buitin set:

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

Dalla bash(1)manpage, sotto la SHELL BUILTIN COMMANDSsezione, comando `set ':

-o option-name
The option-name can be one of the following:
    errexit Same as -e.

3
C'è un modo per salvare (tutte) queste impostazioni e ripristinarle in un secondo momento?
Petr Pudlák,

Corri set -oa conoscere la tua configurazione attuale. Essere espliciti quando si imposta / si annulla qualsiasi di essi negli script.
Dawud,

12

Il comando set +oelenca le impostazioni correnti come comandi che ripristinano lo stesso stato, ad es

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

È possibile ripristinare facilmente tutte le opzioni in un secondo momento, se si salva questo output in una variabile shell:

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

Bash include anche una serie di opzioni non standard (non POSIX) che vengono regolate mediante il shoptcomando. Il comando shopt -ppuò essere utilizzato per salvare queste opzioni in modo simile.

Se si desidera salvare e ripristinare solo un'opzione, è possibile utilizzare la variabile $ - environment, che elenca l'attuale set di opzioni come lettere, ad es.

$ echo $-
himBH

È possibile utilizzare qualcosa del genere per salvare e ripristinare una particolare opzione:

[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e

Nota che è molto importante non perdere le virgolette intorno a "$ SAVED_OPTIONS" nella chiamata di valutazione.
Matt,

3

Utilizzare una trappola di RITORNO

RETURN le trap funzionano anche per gli script di provenienza.

I comandi specificati con una RETURNtrap vengono eseguiti prima che l'esecuzione riprenda dopo una funzione di shell o uno script di shell eseguito con .o sourcerestituito.

- 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

Test

$ ./main_script.sh 
inside main script
errexit         off
inside sourced script
errexit         on
back inside main script
errexit         off

2

Il ripristino delle precedenti impostazioni attivate può essere fatto rapidamente come:

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

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

set -$PREV_SETTING

Al contrario (ripristinando lo stato spento) AFAIK non esiste un tale collegamento e la risposta di Seppo copre tutti i casi.


Il tuo codice come scritto produce -bash: set: -i: invalid optionperché la -ibandiera nota una shell interattiva.
dpw,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.