捕获 INT 和 ERR,但回调被多次执行

dai*_*isy 6 bash trap

我用以下代码捕获 INT 和 ERR

set -ex -o pipefail

dest=$(mktemp -d)
cd "$dest"

trap "echo; echo Clean up; rm -rf $dest" INT ERR
sleep 9999
Run Code Online (Sandbox Code Playgroud)

当我按下^C清理回调被执行多次

++ echo Clean up
Clean up
++ rm -rf /tmp/tmp.KYXL110516
++ echo

++ echo Clean up
Clean up
++ rm -rf /tmp/tmp.KYXL110516
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?是否可以只执行一次?

Jef*_*ler 6

您同时收到 INT 和 ERR 信号;SIGINT 被交给sleep,他以非零返回码退出。然后非零返回码触发 SIGERR 陷阱。

如果 sigspec 为 ERR,则只要管道(可能由单个简单命令组成)、列表或复合命令返回非零退出状态,就会执行命令 arg...

一个例子,查看单独的陷阱:

set -ex -o pipefail
trap "echo Clean up for INT" INT
trap "echo Clean up for ERR" ERR
sleep 9999
Run Code Online (Sandbox Code Playgroud)

执行,然后 Control-C:

+ trap 'echo Clean up for INT' INT
+ trap 'echo Clean up for ERR' ERR
+ sleep 9999
^C++ echo Clean up for INT
Clean up for INT
++ echo Clean up for ERR
Clean up for ERR
Run Code Online (Sandbox Code Playgroud)

至于只调用一次陷阱,一种选择是在ERR陷阱内重置INT陷阱:

...
trap "echo Clean up for INT; trap ERR" INT ERR
...
Run Code Online (Sandbox Code Playgroud)

...这导致:

+ trap 'echo Clean up for INT; trap ERR' INT ERR
+ sleep 9999
^C++ echo Clean up for INT
Clean up for INT
++ trap ERR
Run Code Online (Sandbox Code Playgroud)