I would like to be able to save my current environment in a file (for a running interactive session), so that I can:
I am only interested in exported variables. As I want to be able to restore the environment it have to be a shell function, I am using bash. Ideally, it would not depends on external programs, and would work on versions of bash from v3.2.25 to current.
For now, to save my environment I use the following function:
env_save () {
export -p > "$STORAGE/$1.sh"
}
That I use as env_save <filename>
in a running session. I have some boilerplate code to keep backups, but let's ignore that.
However, I then have difficulties with loading the environment back:
env_restore () {
source "$STORAGE/$1.sh"
}
As this would not remove spurious variables that I created in the mean time. That is, calling export -p
after env_restore <filename>
might not give the same output than cat $STORAGE/$1.sh
.
Is there a clean way to handle that problem? I will probably need to blacklist some variables such as PWD, OLDPWD, SHELL, SHLVL, USER, SSH_*, STORAGE, etc... That is, those variable should not be saved and should not be changed when restoring as they are special variables. I cannot use a whitelist as I do not know what variables will be there.
POSIXly, you can do:
# save
export -p > saved-env
...
# restore
blacklisted () {
case $1 in
PWD|OLDPWD|SHELL|STORAGE|-*) return 0 ;;
*) return 1 ;;
esac
}
eval '
export() {
blacklisted "${1%%=*}" || unset -v "${1%%=*}"
}
'"$(export -p)"
export() {
blacklisted "${1%%=*}" || command export "$@"
}
. saved-env
unset -f export
Note that for bash
not invoked as sh
, you'd need to issue a set -o posix
for that to work properly. Also with bash
versions prior to 4.4, sourcing the output of export -p
is potentially unsafe:
$ env -i 'a;reboot;=1' /bin/bash -o posix -c 'export -p'
export OLDPWD
export PWD="/"
export SHLVL="1"
export a;reboot;
ksh93 has a similar problem. yash
doesn't have that particular one, but still has problems with variable names starting with -
:
$ env -i -- '-p=' yash -c 'export -p'
export '-p'=''
export OLDPWD
export PWD='/'
Also beware of potential problems if you're not in the same locale when saving and restoring the variables.
bash-4.3$ locale charmap
ISO-8859-15
bash-4.3$ export Stéphane=1
bash-4.3$ export -p > a
bash-4.3$ LC_ALL=en_GB.UTF-8 bash -c '. ./a'
./a: line 5: export: `Stéphane=1': not a valid identifier
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments