linux – Bash:为什么当脚本陷阱SIGINT时,父脚本不会在SIGINT终止?

前端之家收集整理的这篇文章主要介绍了linux – Bash:为什么当脚本陷阱SIGINT时,父脚本不会在SIGINT终止?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
script1.sh:
#!/bin/bash    

./script2.sh
 echo after-script

script2.sh:

#!/bin/bash

function handler {
  exit 130
}

trap handler SIGINT

while true; do true; done

当我从终端启动script1.sh,然后使用Ctrl C将SIGINT发送到其进程组时,该信号被script2.sh捕获,当script2.sh终止时,script1.sh将打印“after-script”.但是,我会期望script1.sh在调用script2.sh的行后立即终止.为什么在这个例子中不是这样?

附加说明(编辑):

>由于script1.sh和script2.sh位于同一进程组中,因此在命令行上按Ctrl C时,SIGINT将发送到两个脚本.这就是为什么当脚本2.sh退出时,我不会指望script1.sh继续.
>当script2.sh中的行“陷阱处理程序SIGINT”被注释掉时,script1.sh将在script2.sh存在之后立即退出.我想知道为什么它的行为不一样,因为script2.sh会产生同样的退出代码(130).

解决方法

新答案:

这个问题比我原来怀疑的更有趣.答案基本上在这里给出:

What happens to a SIGINT (^C) when sent to a perl script containing children?

这是相关的tidbit.我意识到你不使用Perl,但我认为Bash正在使用C的惯例.

Perl’s builtin system function works just like the C system(3)
function from the standard C library as far as signals are concerned.
If you are using Perl’s version of system() or pipe open or backticks,
then the parent — the one calling system rather than the one called by
it — will IGNORE any SIGINT and SIGQUIT while the children are
running.

This explanation是我见过的最好的选择.它也说Bash做WCE方法.也就是说,当父进程收到SIGINT时,它等待它的子进程返回.如果处理的处理从SIGINT退出,它也退出SIGINT.如果孩子以其他方式退出,则忽略SIGINT.

There is also a way that the calling shell can tell whether the called
program exited on SIGINT and if it ignored SIGINT (or used it for
other purposes). As in the WUE way,the shell waits for the child to
complete. It figures whether the program was ended on SIGINT and if
so,it discontinue the script. If the program did any other exit,the
script will be continued. I will call the way of doing things the
“WCE” (for “wait and cooperative exit”) for the rest of this document.

我在Bash手册页中找不到这个引用,但我会继续查看信息文档.但是我99%的人相信这是正确的答案.

老回答:

Bash脚本中的命令的非零退出状态不会终止该程序.如果你做一个echo $?之后./script2.sh将显示130.您可以通过使用set -e作为phs建议终止脚本.

$help set
...
-e  Exit immediately if a command exits with a non-zero status.

猜你在找的Linux相关文章