在 bash 脚本中,信号被捕获时会发生什么
In bash script, what happens when a signal is trapped
假设我运行将以下示例另存为hello.sh
#!/bin/bash
hello() {
echo "hello"
}
trap "hello" INT
sleep 100
echo "end"
然后在 shell 我开始 hello.sh
。 1 秒后我按下 Ctrl-C
.
请将 sleep
视为我启动的任何长 运行 进程。
这是我的问题:
- 生成
SIGINT
时,是直接传递给sleep
还是传递给shell脚本?
- 如果是第二个,我可以让
sleep
有机会处理SIGINT
而不传播到它的父hello.sh
吗?
- 如果是第一个,
hello
函数结束后sleep
的状态是什么?
我的测试让我觉得下面的事情是按顺序发生的
sleep
开始 运行
hello.sh
收到信号
- 函数
hello
开始运行
- 函数
hello
完成
echo "end"
开始 运行
- 脚本退出。
但是 sleep
进程在哪个阶段退出以及由于什么原因(例如 SIGINT 停止了 sleep
进程?)
$ cat foo.sh
_sigint()
{
echo "received SIGINT"
}
trap _sigint INT
sleep 10000
echo "status=$?"
$ bash foo.sh # <-- start foo.sh and then press CTRL-C
^Creceived SIGINT
status=130
一些解释:
sleep
作为 bash
的子进程运行。 bash
和 sleep
运行 在同一个 进程组 中,现在是 前台进程组 。
当按下CTRT-C时,会产生SIGINT
,信号会传送到 前台进程组中的所有进程因此bash
和sleep
都将收到SIGINT
.
根据bashmanual(也可以看man bash
)
If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
所以这里 bash
会等待 sleep
被杀死 (默认的 SIGINT 行为是终止进程。参见 signal(7)) 首先然后 bash
运行它的 SIGINT
陷阱。
根据bash手册
The return value of a simple command is its exit status, or 128+n
if the command is terminated by signal n
.
SIGINT
是 2 (参见 kill -l
) 所以 sleep
的退出状态是 128+2=130
.
假设我运行将以下示例另存为hello.sh
#!/bin/bash
hello() {
echo "hello"
}
trap "hello" INT
sleep 100
echo "end"
然后在 shell 我开始 hello.sh
。 1 秒后我按下 Ctrl-C
.
请将 sleep
视为我启动的任何长 运行 进程。
这是我的问题:
- 生成
SIGINT
时,是直接传递给sleep
还是传递给shell脚本? - 如果是第二个,我可以让
sleep
有机会处理SIGINT
而不传播到它的父hello.sh
吗? - 如果是第一个,
hello
函数结束后sleep
的状态是什么?
我的测试让我觉得下面的事情是按顺序发生的
sleep
开始 运行hello.sh
收到信号- 函数
hello
开始运行 - 函数
hello
完成 echo "end"
开始 运行- 脚本退出。
但是 sleep
进程在哪个阶段退出以及由于什么原因(例如 SIGINT 停止了 sleep
进程?)
$ cat foo.sh
_sigint()
{
echo "received SIGINT"
}
trap _sigint INT
sleep 10000
echo "status=$?"
$ bash foo.sh # <-- start foo.sh and then press CTRL-C
^Creceived SIGINT
status=130
一些解释:
sleep
作为bash
的子进程运行。bash
和sleep
运行 在同一个 进程组 中,现在是 前台进程组 。当按下CTRT-C时,会产生
SIGINT
,信号会传送到 前台进程组中的所有进程因此bash
和sleep
都将收到SIGINT
.根据bashmanual(也可以看
man bash
)If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
所以这里
bash
会等待sleep
被杀死 (默认的 SIGINT 行为是终止进程。参见 signal(7)) 首先然后bash
运行它的SIGINT
陷阱。根据bash手册
The return value of a simple command is its exit status, or
128+n
if the command is terminated by signaln
.SIGINT
是 2 (参见kill -l
) 所以sleep
的退出状态是128+2=130
.