How to properly restore settings when running a script using "source"?
Exactly the same way you activate it: calling the buitin set
:
$ set -o errexit
$ set -o | grep errexit
errexit on
$ set +o errexit
$ set -o | grep errexit
errexit off
From the bash(1)
manpage, under the SHELL BUILTIN COMMANDS
section, `set' command:
-o option-name
The option-name can be one of the following:
errexit Same as -e.
The command set +o
lists the current settings as commands that restore the same state, e.g.
$ set +o
set +o allexport
set -o braceexpand
set -o emacs
set +o errexit
set +o errtrace
...
You can easily restore all the options later, if you save this output to a shell variable:
SAVED_OPTIONS=$(set +o)
set -e
# do something
eval "$SAVED_OPTIONS"
Bash includes also a number of non-standard (not POSIX) options that are adjusted using shopt
command. The command shopt -p
can be used to save these options in a similar fashion.
If you only want to save and restore one option, you can use the $- environment variable, which lists the current set of options as letters, e.g.
$ echo $-
himBH
You could use something like this to save and restore a particular option:
[[ $- = *e* ]]
SAVED_ERREXIT=$?
set -e
# do something
(( $SAVED_ERREXIT )) && set +e
Use a RETURN trap
RETURN
traps work for sourced scripts, too.
Commands specified with an
RETURN
trap are executed before execution resumes after a shell function or a shell script executed with.
orsource
returns.– 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
Restoring previous activated settings can be quickly done as:
PREV_SETTING=$- # e.g. himxBH (there was xtrace)
set +x
# do your script without xtrace, ...
set -$PREV_SETTING
The other way around (restore to the off state) AFAIK there isn't such a shortcut and Seppo's answer covers all cases.