Temporary workspaces let shell scripts assemble reports, archives, or converted data without mixing partial files into the final destination. A script that exits before its last command can leave that workspace behind unless cleanup is tied to the shell lifecycle.
The Bash EXIT pseudo-signal runs its trap before the shell terminates. Capturing $? at the start of the handler preserves the pending result, so a failed workload still reports failure after its files are removed.
The mktemp command creates an unpredictable directory name and prints the resulting path. Initializing the variable before trap registration, checking that it is nonempty, and requiring an existing directory constrain recursive removal to the workspace created by the script.
Related: How to create and run a Bash script
Related: How to use here-documents in Bash
#!/usr/bin/env bash set -euo pipefail mode=${1:-ok} workdir=
Initializing workdir keeps the later guard valid if the shell exits before mktemp assigns a path.
cleanup() { local status=$? trap - EXIT if [[ -n $workdir && -d $workdir ]]; then rm -rf -- "$workdir" printf 'removed %s\n' "$workdir" fi exit "$status" }
The quoted rm operand receives only the path stored by mktemp after both guards succeed. Recursive removal can destroy unrelated data if the variable is assigned from another source.
trap cleanup EXIT
workdir=$(mktemp --directory "${TMPDIR:-/tmp}/report-cleanup.XXXXXX") printf 'created %s\n' "$workdir" printf 'report data\n' > "$workdir/report.txt" if [[ $mode == fail ]]; then printf 'simulated failure\n' >&2 false fi printf 'finished work\n'
The fail argument supplies a controlled nonzero path for testing the handler; the default path reaches the final success message.
#!/usr/bin/env bash set -euo pipefail mode=${1:-ok} workdir= cleanup() { local status=$? trap - EXIT if [[ -n $workdir && -d $workdir ]]; then rm -rf -- "$workdir" printf 'removed %s\n' "$workdir" fi exit "$status" } trap cleanup EXIT workdir=$(mktemp --directory "${TMPDIR:-/tmp}/report-cleanup.XXXXXX") printf 'created %s\n' "$workdir" printf 'report data\n' > "$workdir/report.txt" if [[ $mode == fail ]]; then printf 'simulated failure\n' >&2 false fi printf 'finished work\n'
$ bash -n temp-cleanup.sh
$ bash temp-cleanup.sh created /tmp/report-cleanup.xAawk7 finished work removed /tmp/report-cleanup.xAawk7
$ ls -ld /tmp/report-cleanup.xAawk7 ls: cannot access '/tmp/report-cleanup.xAawk7': No such file or directory
$ bash temp-cleanup.sh fail created /tmp/report-cleanup.wc7Ege simulated failure removed /tmp/report-cleanup.wc7Ege
$ printf 'exit_status=%d\n' "$?" exit_status=1
Status 1 shows that cleanup did not convert the failed workload into a successful script result.
$ ls -ld /tmp/report-cleanup.wc7Ege ls: cannot access '/tmp/report-cleanup.wc7Ege': No such file or directory