Single-quote trap so variables expand later

SC2064: `trap "cleanup $tmpdir" EXIT` expands `$tmpdir` when the trap is set, not when it fires. Use single quotes.

Problem

Double quotes expand variables when the `trap` command runs, freezing the value. If `$tmpdir` changes later, the trap deletes the wrong path — or nothing at all.

Bad

trap "rm -rf $tmpdir" EXIT

Good

trap 'rm -rf "$tmpdir"' EXIT

Explanation

Single quotes defer expansion until the signal handler runs. Combine with double quotes inside so the value is safely quoted at that point too.

When It Matters

A trap argument is a string that gets evaluated when the signal fires, but a double-quoted trap expands its variables at the moment the trap is installed. That is usually the opposite of what a cleanup handler needs: the temporary directory variable is often reassigned, or not yet assigned, when the trap line runs. The failure mode is genuinely dangerous. If tmp is empty when the trap is registered, a double-quoted trap "rm -rf $tmp" bakes in "rm -rf " with no operand at best — and with a stray glob or a later-assigned relative path, it can delete something you did not intend.

Second Example

Note

Single quotes defer the expansion to signal time; double quotes bind the value at registration time. Both are valid — pick deliberately.

Exceptions

Early binding is sometimes exactly what you want: capturing the value a variable had when the trap was installed, before a loop overwrote it, requires double quotes. Keep it, but make the intent obvious with a comment and add "# shellcheck disable=SC2064" so a future reader knows the expansion timing was chosen, not overlooked.

Faq

Q

When does a single-quoted trap expand its variables?

A

At the moment the signal arrives and the shell evaluates the trap string, so it sees the values current at that point in the script.

Q

Can a trap call a function instead?

A

Yes, and it is usually cleaner: trap cleanup EXIT, with cleanup defined as a normal function. The function body is parsed once and reads current variable values when it runs, which sidesteps the quoting question entirely.

Q

Does an EXIT trap run when the script is killed?

A

It runs on normal exit and on signals that the shell handles, but not on SIGKILL. Register the signals you care about explicitly: trap cleanup EXIT INT TERM.