Temporary files and directories can remain behind when a Bash script exits before its normal cleanup line runs. An EXIT trap gives the script one cleanup path that runs when the shell leaves after normal completion or after a command failure.
The trap builtin registers a command or function for shell events. Pairing mktemp -d with a cleanup function keeps the temporary path unique and lets the function remove only the directory that the script created.
The script writes the temporary directory path to a small check file so the cleanup can be verified after the shell exits. The cleanup function saves $? before removing files and returns that status, so a successful cleanup does not hide a failed script. Treat rm -rf as sensitive: quote the variable, guard against an empty value, and keep it limited to the path returned by mktemp.
Related: How to create and run a Bash script
Related: How to use here-documents in Bash
#!/usr/bin/env bash set -euo pipefail path_file=${1:-cleanup.path} mode=${2:-ok} workdir= cleanup() { status=$? if [ -n "$workdir" ] && [ -d "$workdir" ]; then rm -rf -- "$workdir" printf "removed %s\n" "$workdir" fi return "$status" } trap cleanup EXIT workdir=$(mktemp -d) printf "%s\n" "$workdir" > "$path_file" printf "created %s\n" "$workdir" printf "report data\n" > "$workdir/report.txt" if [ "$mode" = "fail" ]; then printf "simulated failure\n" >&2 exit 1 fi printf "finished work\n"
The cleanup function uses rm -rf. Keep the temporary directory variable quoted and guarded so an empty or unintended path is not removed.
workdir starts empty before the trap is registered. That keeps the cleanup guard safe if the script exits before mktemp creates a directory.
$ bash -n temp-cleanup.sh $ printf 'syntax ok\n' syntax ok
$ bash temp-cleanup.sh cleanup.path created /tmp/tmp.zV2Og8JWKj finished work removed /tmp/tmp.zV2Og8JWKj
$ cleanup_dir=$(cat cleanup.path) $ test ! -d "$cleanup_dir" $ printf 'temporary directory removed\n' temporary directory removed
$ bash temp-cleanup.sh cleanup.path fail created /tmp/tmp.lsN3VcJh0H simulated failure removed /tmp/tmp.lsN3VcJh0H
The command exits with status 1 after printing the simulated failure, but the EXIT trap still runs before Bash returns control to the parent shell.
If the script needs custom INT or TERM handling, use a handler that exits after setting the intended status. A signal trap that only runs cleanup and returns can let the script continue after the handler finishes.
$ cleanup_dir=$(cat cleanup.path) $ test ! -d "$cleanup_dir" $ printf 'temporary directory removed after failure\n' temporary directory removed after failure