Files and data

Create and clean temporary files

Use mktemp and a trap so unique temporary data is removed on success, failure, or interruption.

10 minute lesson

~~~

Scripts need scratch space: an archive to assemble, a download to inspect, a sorted copy of a log. Hardcoding a path like /tmp/work.txt looks harmless, but predictable temporary filenames can collide or be replaced by another user on a shared machine. mktemp asks the operating system for a unique private path instead.

Create a temporary directory with cleanup

work=$(mktemp -d)
cleanup() { rm -rf -- "$work"; }
trap cleanup EXIT INT TERM

printf 'working in %s\n' "$work"
# working in /tmp/tmp.X8s2Lk4bQz

mktemp -d creates a directory only your user can access and prints its path, which we capture with command substitution.

The trap line makes this reliable. A trap registers a command to run when the shell receives a signal or, with the special EXIT condition, whenever the script ends. This one runs cleanup on normal exit, on Ctrl-C (INT), and on termination (TERM) — so the directory disappears whether the script succeeds, fails, or gets interrupted halfway.

The -- in rm -rf -- "$work" ends option parsing, so even a path starting with a dash can’t be misread as a flag.

Verify the cleanup runs

Exit normally and interrupt the script. Confirm the exact generated directory is removed both times:

./make-report
# working in /tmp/tmp.QpB7wq2c1M
ls /tmp/tmp.QpB7wq2c1M
# ls: cannot access '/tmp/tmp.QpB7wq2c1M': No such file or directory

Run it again and press Ctrl-C mid-run, then check again. If the directory survives an interrupt, the trap was registered too late — register it immediately after creating the resource, before any work that can fail.

The failure mode to fear

rm -rf next to a variable that might be empty is the classic shell disaster:

rm -rf "$workdir/cache"   # if $workdir is empty: rm -rf /cache

Validate the variable before any recursive deletion. set -u catches unset names, and a one-line guard costs nothing:

[[ -n $work ]] || exit 1

Never build a destructive target from an empty or broad environment variable. The pattern above — mktemp output, straight into a trap — is safe precisely because the value comes from a program you just ran, not from inherited environment.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →