I do exec bash
. It cleans up variables and functions. It shouldn't clean up newly opened file descriptors (with exec $someNumber<>somefile
) or exported variables, but I rarely open new files with exec
and my startup files (which get loaded when you do exec bash
) restore environment variables I care about (such as PATH
) to the state I want them in.
(
Doing a plain bash
has the disadvantage that it'll stick another shell to your current one so then you'll have to exit
one additional time.
)
If I don't care about cleaning up extra variables and functions, I just re-load the dot files.
I edit ~/.bashrc
and reload it fairly often so I have a keyboard shortuct for the combo:
bashrcEdit() { $EDITOR "$HOME/.bashrc"; }
bind -x '"\C-e": bashrcEdit && bashrcReload'
and for plain reloading:
bind -x '"\C-o": bashrcReload;'
(
My reload function is:
bashrcReload() { unset bashrcSourced; unset PROFILE_SOURCED; source "$HOME/.bashrc"; }
instead of just:
source "$HOME/.bashrc";
It has the unset
s because those variables (first nonexported—for .bashrc
, second exported—for .profile
) serve as double include guards in my setup–without those unset
s, source
ing .bashrc
would be a no-op in my setup.
)
Doing it right
If you want to be thorough, you can
- snapshot the environment at the end of your .bashrc (and then reload it--this you can do perfectly)
- snapshot which filedescriptors are open (and then close all others--this isn't and never can be a perfect solution)
Add this at the end of your .bashrc
:
#Take a snapshot of the env and fds
envSnap() {
export FDS="$(/bin/ls /proc/$$/fd/)"
export ENV="$(export -p)"
}
#Restore env, close extra fds, and re-exec bash
envRestore(){
exec env - ENV="$ENV" bash --noprofile -c '
eval "$ENV"
for fd in `{ /bin/ls /proc/$$/fd; echo "$FDS"; } | sort | uniq -u`; do
eval "exec $fd>&-"
done
exec bash
'
}
#Take the snapshot now
envSnap
Now you can do envRestore
to pretty much perfectly restore the environment.
E.g., if you do:
export FOO=bar
touch file
exec 5<file
Then after an exec bash
, you'll still have:
/bin/ls /proc/self/fd
include 5, and echo $FOO
print bar
.
If you do envRestore
instead of exec bash
, however, then /bin/ls/ /proc/self/fd
shouldn't include 5 (unless your bash usually starts with fd 5 open) and echo $FOO
should print an empty line.
(File descriptors are a weak point of this, because closing the extra filedescriptors doesn't guarantee that the original file descriptors weren't redirected or that the vtable entries they point at haven't been changed in a way that will change how reads or writes on that filedescriptor will behave.)
. /etc/profile && . ~/.profile
, but it didn't come to mindexec
. So for now, it would be a combination ofexec
,source
andunset
. Any other additions? – 1.61803 Nov 20 '15 at 19:56env
dumper from scratch) so that the output is shell eval'lable. – Petr Skocik Nov 20 '15 at 20:10envSnapshot
custom-compiled executable! Although now that I wrote the c file, I'm kind of emotionally attached to it. – Petr Skocik Nov 21 '15 at 15:59export -p
, thanks mikeserv! – Petr Skocik Nov 21 '15 at 16:06set
, aliases w/alias
, environment (to the extent the shell can reliably duplicate it at all),export -p
,readonly -p
for read only variables. inbash
you can get functions as well w/declare -fp
. – mikeserv Nov 21 '15 at 16:13