Her*_*che 12 linux bash process
script1.sh:
#!/bin/bash
./script2.sh
echo after-script
Run Code Online (Sandbox Code Playgroud)
script2.sh:
#!/bin/bash
function handler {
exit 130
}
trap handler SIGINT
while true; do true; done
Run Code Online (Sandbox Code Playgroud)
当我从终端启动script1.sh,然后使用Ctrl + C将SIGINT发送到其进程组时,该信号被script2.sh捕获,当script2.sh终止时,script1.sh将打印"after-script".但是,我原本希望script1.sh在调用script2.sh的行之后立即终止.为什么在这个例子中不是这种情况?
补充说明(编辑):
由于script1.sh和script2.sh位于同一进程组中,因此在命令行上按Ctrl + C时,会将SIGINT发送到这两个脚本.这就是为什么我不希望script2.sh在script2.sh退出时继续.
当注释掉script2.sh中的"陷阱处理程序SIGINT"行时,script1.sh会在script2.sh存在后立即退出.我想知道为什么它的行为不同,因为script2.sh只产生相同的退出代码(130).
sea*_*mcl 11
新答案:
这个问题比我原先怀疑的要有趣得多.答案主要在这里给出:
发送到包含子节点的perl脚本时,SIGINT(^ C)会发生什么?
这是相关的花絮.我意识到你没有使用Perl,但我认为Bash正在使用C的约定.
就信号而言,Perl的内置系统功能就像标准C库中的C系统(3)功能一样工作.如果您正在使用Perl的system()版本或管道打开或反引号,那么父级 - 一个调用系统而不是它所调用的系统 - 将在子级运行时忽略任何SIGINT和SIGQUIT.
这个解释是我见过的关于可以做出的各种选择的最好的解释.它还说Bash采用WCE方法.也就是说,当父进程收到SIGINT时,它会等待其子进程返回.如果处理的进程退出SIGINT,它也会退出SIGINT.如果孩子以任何其他方式退出,则忽略SIGINT.
还有一种方法是调用shell可以判断被调用的程序是否在SIGINT上退出,以及它是否忽略了SIGINT(或将其用于其他目的).与WUE方式一样,shell等待孩子完成.它计算程序是否在SIGINT上结束,如果是,则停止脚本.如果程序执行任何其他退出,则脚本将继续.对于本文档的其余部分,我将称之为"WCE"(用于"等待和合作退出")的方式.
我在Bash手册页中找不到对此的引用,但我会继续查看info文档.但我有99%的信心这是正确的答案.
老答案:
Bash脚本中命令的非零退出状态不会终止该程序.如果你做了echo $?之后./script2.sh它会显示130.你可以使用set -ephs建议终止脚本.
$ help set
...
-e Exit immediately if a command exits with a non-zero status.
Run Code Online (Sandbox Code Playgroud)