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.

Steps to clean up temporary files in Zsh with trap:

  1. 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.

  1. 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.

  2. Run the script through the normal path.
    $ zsh temp-cleanup.zsh cleanup.path
    created /tmp/tmp.467voMLHRt
    finished work
    removed /tmp/tmp.467voMLHRt
  3. Read the temporary directory path saved by the script.
    $ cleanup_dir=$(cat cleanup.path)
  4. Verify that the saved path no longer exists after the normal exit.
    $ test ! -d "$cleanup_dir" && printf 'removed\n'
    removed
  5. 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.

  6. Read the temporary directory path from the failed run.
    $ cleanup_dir=$(cat cleanup.path)
  7. Verify that the failed run also removed its temporary directory.
    $ test ! -d "$cleanup_dir" && printf 'removed after failure\n'
    removed after failure
  8. Remove the sample script and check file.
    $ rm -f cleanup.path temp-cleanup.zsh