Temporary directories created by a Zsh script can remain on disk when a command fails or the operator interrupts the run. A cleanup trap gives the script a final handler that removes temporary state before the shell process exits.
The trap builtin registers code for shell events such as EXIT. Pairing mktemp -d with a cleanup function keeps the workspace unique and limits removal to the directory that the script created.
The sample writes the temporary directory path to cleanup.path so the parent shell can verify removal after Zsh exits. It saves the original exit code before removing files, then returns that code so cleanup does not hide a failed command. Treat the cleanup's rm -rf as sensitive by guarding the variable, quoting the path, and using -- before the directory name. A trap cannot run after KILL, power loss, or a hard process crash, so temporary data still needs a separate recovery path when it must be kept.
Related: How to debug a Zsh script
Related: How to use conditionals in Zsh
Related: Clean up temporary files in Bash with trap
Steps to clean up temporary files in Zsh with trap:
- Create a Zsh script that registers a cleanup function before temporary work starts.
- temp-cleanup.zsh
#!/usr/bin/env zsh emulate -L zsh setopt err_exit no_unset pipe_fail path_file=${1:-cleanup.path} mode=${2:-ok} workdir= cleanup() { local exit_status=$? if [ -n "${workdir:-}" ] && [ -d "$workdir" ]; then rm -rf -- "$workdir" print -r -- "removed $workdir" fi return $exit_status } trap cleanup EXIT trap 'exit 130' INT trap 'exit 143' TERM workdir=$(mktemp -d) print -r -- "$workdir" > "$path_file" print -r -- "created $workdir" print -r -- "report data" > "$workdir/report.txt" if [ "$mode" = fail ]; then print -u2 -- "simulated failure" exit 1 fi print -r -- "finished work"
The cleanup function uses rm -rf. Keep $workdir quoted, guarded, and assigned only from mktemp -d so the script does not remove an unintended path.
Zsh uses status as a special parameter, so the cleanup function saves the code in exit_status. The INT and TERM traps exit with signal-style status codes, then the EXIT trap runs cleanup once.
- Check the script syntax before running it.
$ zsh -n temp-cleanup.zsh
No output from zsh -n means Zsh parsed the file without finding a syntax error.
- Run the script through the normal path.
$ zsh temp-cleanup.zsh cleanup.path created /tmp/tmp.467voMLHRt finished work removed /tmp/tmp.467voMLHRt
- Read the temporary directory path saved by the script.
$ cleanup_dir=$(cat cleanup.path)
- Verify that the saved path no longer exists after the normal exit.
$ test ! -d "$cleanup_dir" && printf 'removed\n' removed
- Run the script through the failure path.
$ zsh temp-cleanup.zsh cleanup.path fail created /tmp/tmp.BAWcdhSlDC simulated failure removed /tmp/tmp.BAWcdhSlDC
The command exits with status 1 after printing simulated failure, but the cleanup function returns the saved status after removing the temporary directory.
- Read the temporary directory path from the failed run.
$ cleanup_dir=$(cat cleanup.path)
- Verify that the failed run also removed its temporary directory.
$ test ! -d "$cleanup_dir" && printf 'removed after failure\n' removed after failure
- Remove the sample script and check file.
$ rm -f cleanup.path temp-cleanup.zsh
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.