Sorry for excavating this, but just found it and wanted to try.
Will offer what I can.
#! /bin/bash
This is no crime, but it's a tad more portable (if that matters at all to you) if you use
#! /bin/env bash
env
itself is virtually always in /bin
, though some installations move the interpreter binaries.
I don't personally like or use set -e
. It doesn't give me as much control over what happens. Personally, I prefer trap
s, something like this:
trap 'echo "ERROR $? at $0:$LINENO - [$BASH_COMMAND]"' err
Then I get useful feedback.
$: bogus
bash: bogus: command not found
ERROR 127 at /usr/bin/bash:73 - [bogus]
As for the eval
, how about creating a controlled file to source at exit time?
atexit_handler() {
tmp=$(mktemp)
printf "%s\n" "${ATEXIT[@]}" >| $tmp
trap 'echo "Error $? in exit handler when processing [$BASH_COMMAND]"' err
. $tmp
}
This would allow for more arbitrarily complex possibilities, without really worsening the security risk of the eval
, which isn't catastrophic if your code registers all the commands going into the handler anyway. It also leaves you the option of scheduling the cleanup of the file with the handler, so that if it succeeds it leaves no mess, but if it fails will abort and let you debug the file.
atexit true
atexit "echo bye"
atexit 'sing() { for i in do re me;do echo "$i"; done; }'
atexit sing
atexit false
atexit 'rm $tmp' # defer evaluation
I love this idea, btw. I may start using it. :)