Problem
Quite a few of the bash scripts I write create temporary resources (temporary directories and files) which need to be cleaned up when the scripts terminate. Here is a little trick I use to make this task a little simpler.
Idea
The idea is to define a function named cleanup
in which all cleanup tasks are defined. This function also contains all necessary actions to figure out what actually needs to be cleaned up (e.g if a file actually exists). This function is then registered with trap
[1] so that it is executed when the script terminates.
Example
#!/bin/bash
set -e -o pipefail
function cleanup {
EXIT_CODE=$?
set +e # disable termination on error
if [[ -n $TMP_DIR ]]; then
rm -Rf $TMP_DIR
echo "deleted dir $TMP_DIR"
fi
exit $EXIT_CODE
}
trap cleanup EXIT
TMP_DIR=$(mktemp -d) # create temporary directory
echo "created dir $TMP_DIR"
pushd $TMP_DIR # change dir to $TMP_DIR
# do something which gets cleaned up when done
touch a.txt
touch b.txt
Exit Code Propagation
Because the cleanup function will also be called if something goes wrong (the set -e
call in the second line of the script changes the execution behaviour to “Exit immediately”[2]) we also do want to propagate the EXIT CODE[3] of the actual script to the caller.
So the first thing we do in the cleanup function is to capture that exit code in the variable EXIT_CODE
and then disable the “Exit immediately” behaviour with set +e
. The final thing in the cleanup function is then to exit with the original exit code.