With zsh 5.8, the SIGPIPE trap is not executed when the builtin that generates it is the last command of a subshell: zira% ( trap 'echo PIPE >&2' PIPE; sleep 1; pwd; ) | : zsh: write error: broken pipe With an additional command (builtin), this is OK: zira% ( trap 'echo PIPE >&2' PIPE; sleep 1; pwd; :; ) | : zsh: write error: broken pipe PIPE I wonder whether this is related to the (undocumented?) optimization that exec's the last command of a subshell / shell script (though this is not applicable to builtins). This also occurs with zsh 5.7.1-1 in Debian 10 (buster). There is the same issue with mksh, but not with dash, ksh93, bash and yash.