I’m just going to leave this here and then quietly back away before the flames start.
#!/bin/bash # Stackable atexit functionality for bash. # # Bash's "trap ... EXIT" is somewhat similar to libc's "atexit" with the # limitation that such functions don't stack. If you use this construct twice, # the cleanup code in the second invocation *replaces* that in the first, so # the first actually doesn't happen. Oops. This snippet shows a way to get # stackable behavior by editing the current trap function to incorporate a new # one, either at the beginning or the end. That's a really cheesy thing to do, # but it works. function atexit_func { # Bash doesn't have anything like Python's 'pass' so we do nothing # this way instead. echo -n } trap "atexit_func" EXIT # Call this function to have your cleanup called *before* others. function atexit_prepend { tmpfile=$(mktemp atexit.XXXXXX) typeset -f atexit_func > $tmpfile echo -en "2a\n$1\n.\nw\nq\n" | ed - $tmpfile . $tmpfile rm $tmpfile } # Call this function to have your cleanup called *after* others. function atexit_append { tmpfile=$(mktemp atexit.XXXXXX) typeset -f atexit_func > $tmpfile echo -en "\$i\n$1\n.\nw\nq\n" | ed - $tmpfile . $tmpfile rm $tmpfile } function first_atexit { echo "first atexit function" } atexit_append first_atexit function second_atexit { echo "second atexit function" } atexit_append second_atexit function third_atexit { echo "third atexit function" } atexit_prepend third_atexit # Should see third/first/second here. |
This is scarily close to Lisp macros in bash… My brain hurts now, thanks! :)
> Bash doesn’t have anything like Python’s ‘pass’
You can just use : (that’s a colon). It’s been a standard feature in the shell for at least 30 years.
$ type :
: is a shell builtin
$ help :
:: :
No effect; the command does nothing. A zero exit code is returned.
Learn something every day, I guess. Thanks!
You’re welcome. It’s even nicer than pass, because it ignores all its arguments. You can use it to effectively comment out a single line of an if or else etc., without winding up with invalid syntax (due to an empty block). It’s also very useful in
while :
do
done