在bash脚本中,捕获信号时会发生什么

  • 本文关键字:信号 脚本 bash bash shell
  • 更新时间 :
  • 英文 :


假设我正在运行以下保存为hello.sh的示例

#!/bin/bash
hello() {
echo "hello"
}
trap "hello" INT
sleep 100
echo "end"

并且在shell中我启动CCD_ 2。1秒后,我按下Ctrl-C

请将sleep视为我开始的任何长期过程。

以下是我的问题:

  1. 生成SIGINT时,它是直接传递到sleep还是传递到shell脚本
  2. 如果是第二个,我可以让sleep有机会处理SIGINT,并且不传播到其父hello.sh
  3. 如果是第一个,hello功能完成后,sleep的状态如何

我的测试让我觉得以下是按顺序发生的

  1. sleep开始运行
  2. hello.sh收到信号
  3. 函数hello开始运行
  4. 功能hello完成
  5. echo "end"开始运行
  6. 脚本退出

但是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作为hello.sh0的子进程运行。bashsleep在同一进程组中运行,该进程组现在是前台进程组

  • 按下CTRT-C时,它将生成SIGINT,信号将发送到前台进程组中的所有进程,因此bashsleep都将接收SIGINT

  • 根据bash手册(也可以参见man bash(

    如果bash正在等待命令完成并接收到已设置陷阱的信号,则在命令完成之前,陷阱将不会执行

    所以这里bash将等待sleep被杀死(默认的SIGINT行为是终止进程。参见信号(7((,然后bash运行其SIGINT陷阱。

  • 根据bash manaul

    简单命令的返回值是其退出状态,如果命令由信号n终止,则返回值为128+n

    SIGINT为2(请参阅kill -l(,因此sleep的退出状态为128+2=130

相关内容

  • 没有找到相关文章

最新更新