我遇到了这种奇怪的行为trap
。
根据trap 的联机帮助页:
当进入子 shell 时,未被忽略的陷阱将设置为默认操作。这并不意味着不能在子 shell 中使用 trap 命令来设置新陷阱。
我是这样解释的:
- 如果脚本捕获信号 A,其子 shell 也会捕获信号 A,但采用默认操作。
- 子 shell 还可以指定另一个操作来捕获相同的信号
为了测试我的理解,我有两个脚本:
outerscript.sh
#!/bin/bash
trap "echo SIGINT in outer" SIGINT
echo PID of outer process: $$
echo -----------;
./innerscript.sh
innerscript.sh
#!/bin/bash
echo start inner script
echo PID of inner process: $$
trap "SIGINT in inner, do graceful shutdown" SIGINT
sleep 10s
echo done inner process
然后我运行外部脚本 然后./outerscript.sh
外部脚本将调用内部脚本并创建一个子shell,如图所示
在睡眠命令期间,我发送一个SIGINT
withkill -SIGINT <pid>
根据接收信号的PID结果不同
接收信号的PID为外标PID
请注意,我仍然需要等待 sleep 命令完成
done inner process SIGINT in outer
接收信号的PID是innerscript的PID
请注意,我仍然需要等待 sleep 命令完成
SIGINT: command not found done inner process
PID接收信号是sleep信号
请注意,我不必等待睡眠命令完成
done inner process
问题
在情况 2) 中,为什么会出现该错误?我预计innerscript会触发它的陷阱功能。
在情况3)中,为什么它甚至会触发innerscript的trap函数?我预计它会自杀并正常返回到内部脚本进程。
答案1
有 2 个问题。情况2的错误是因为系统上没有名为SIGINT的命令。 OP 有
trap "SIGINT in inner, do graceful shutdown" SIGINT
但可能所需的命令是
trap "echo SIGINT in inner, do graceful shutdown" SIGINT
另一个问题询问为什么内部脚本陷阱函数被调用,但事实并非如此。睡眠进程被终止,脚本移至下一行。