stank icon indicating copy to clipboard operation
stank copied to clipboard

trap considered harmful

Open mcandre opened this issue 2 years ago • 13 comments

We could implement a crude, multiline regex scanner to warn on the use of traps in concert with exec, which presents a hazard. The script author should be made aware that traps do not persist into exec environments.

Related: https://github.com/koalaman/shellcheck/issues/2631

Frankly, trap is such an unwieldy tool that we may even recommend against writing reusable traps and recommend instead the use of <failable command> || <backup command> and/or if [ ! <failable command> ]; then ... fi.

Instead of subshells, the script author can redirect output to a file, then read the file back.

Sadly, the simple die / panic command is unavailable in most shells.

Another hazard of traps is that many authors forget to implement them for conditions other than EXIT. Ultimately, it may be prudent to recommend rewriting a script with any traps, in a more competent application language such as Go or Ruby. We can then use a simple, single line regex to scan for uncommented arbitrary indentation, trap commands.

Note the more common interpolated subshells "$(...)" and backticks, whose failure may not trigger the desired traps.

Note that zsh function traps still present a conflict with exec, and require a separate, multiline regex to detect. (Though two single line regexes used in tandem will be more efficient.)

That leaves parenthesis subshells as the last trigger for warnings, when not prefixed by a string interpolation dollar sign. That includes nested subshells within larger string interpolation. Anyway, subshells should trigger warnings when list traps are used, unless the interpreter is zsh, or bash with set -E enabled.

mcandre avatar Jan 29 '23 18:01 mcandre

POSIX sh traps do not persist across subshell boundaries.

bash traps can persist if set -E is enabled.

zsh function traps persist but not classic list traps.

mcandre avatar Jan 30 '23 15:01 mcandre

ash and dash: -E indicates the Emacs text editor. Traps do not persist across subshell boundaries.

mcandre avatar Jan 30 '23 15:01 mcandre

posh: Traps do not persist across subshell boundaries.

mcandre avatar Jan 30 '23 15:01 mcandre

ksh: Traps do not persist across subshell boundaries.

mcandre avatar Jan 30 '23 15:01 mcandre

mksh, oksh, pdksh, rksh: Missing functionality for the ERR, EXIT, and DEBUG signals. Traps do not persist across subshell boundaries.

mcandre avatar Jan 30 '23 15:01 mcandre

Thompson sh, tsh, etsh: No documented support for traps.

mcandre avatar Jan 30 '23 15:01 mcandre

yash: Traps do not persist across subshells.

mcandre avatar Jan 30 '23 15:01 mcandre

lksh: Unknown trap, subshell support. Predates bash. Implementation retrofitted using mksh. No interactive support. Traps do not persist across subshell boundaries.

mcandre avatar Jan 30 '23 16:01 mcandre

fish, ion, PowerShell: Lack of scoped subshells, although command interpolated incidental subshells may be available. Traps may not persist across interpolated incidental subshell boundaries.

ion appears to lack traps for error and exit signals.

Not POSIX, but noting for posterity.

mcandre avatar Jan 30 '23 16:01 mcandre

Note also that the ERR is not a POSIX signal for use when configuring traps.

https://www.shellcheck.net/wiki/SC3047

mcandre avatar Jan 30 '23 23:01 mcandre

Note that interpolated strings (both dollar paren and backtick) introduce subshells, but not arithmetic expressions.

mcandre avatar Jan 31 '23 00:01 mcandre

Note that a pipe also creates a subshell.

Unknown whether the three operators ;, && and/or || technically create subshells or not.

Ditching checking for subshells entirely. A modern shell script of medium size is very likely to invoke a subshell, so we might as well warn for traps regardless.

For non-bash, non-zsh shells, we simply warn that any and all traps are reset in subshells. Rather than document an exhaustive list of alternatives, we leave it to the user to decide how to resolve this. Bash and zsh get more specific warnings, due to their ability to enable certain trap safety features.

mcandre avatar Jan 31 '23 00:01 mcandre

Reopening.

Plan to mark all classic POSIX traps as risky due to implicit reset behavior.

mcandre avatar Mar 02 '23 00:03 mcandre