小编Gab*_*iel的帖子

由于信号,bash不会在子进程异常退出时退出

我真的很努力去理解我做错了什么,为什么?

我有一个launch.sh启动process.sh.

启动文件

#!/bin/bash
while true; do 
./process.sh 
done
Run Code Online (Sandbox Code Playgroud)

进程文件

#!/bin/bash
function signalHandler() {
    for i in {1..2}; do
        sleep 0.1s
        echo "process.sh: cleanup $i"
    done
    exit 130
}

trap "signalHandler" "SIGINT"

while true; do 
sleep 1s
done
Run Code Online (Sandbox Code Playgroud)

当我跑

./launch.sh &
Run Code Online (Sandbox Code Playgroud)

然后用它杀死它

kill -s SIGINT -$!    
Run Code Online (Sandbox Code Playgroud)

where$!获取最后一个命令 (launch.sh) 的 PID,减号将信号发送给所有孩子,然后launch.sh继续。为什么?


我期望以下行为(根据此博客Signal & Bash):

launch.sh在后台运行脚本的外壳 A被中断,Bash 等待process.sh完成。由于process.sh异常返回(出射130)由于在信号处理程序process.sh,外壳A应该退出。为什么不呢?

如果这个孩子的状态表明它由于那个信号而异常退出,shell 会清理,删除它的信号处理程序,并再次杀死自己以触发操作系统默认操作(异常退出)。或者,它按照陷阱设置运行脚本的信号处理程序,然后继续。

bash process signals exit

6
推荐指数
1
解决办法
1201
查看次数

向命令管道发送信号拆除整个管道

我有一个两个过程的简单示例

第一个是一个简单的循环,它进行一些处理

#!/bin/bash
function signalHandler() {
    echo "sig: $1 received ==> exit"
    for i in {1..5}; do
        echo "cleanup $i %"
        sleep 1
    done
    trap SIGINT
    kill -INT $$
}

trap signalHandler SIGUSR2

for i in {1..100000}; do
    echo "doing stuff $i %"
    sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)

我像这样启动了脚本:

./script.sh | grep "wow"
Run Code Online (Sandbox Code Playgroud)

我附加了一个辅助 grep 命令只是为了演示。

grep当我仅向进程 ( )发送 USR2 信号时kill USR2 $(pgrep grep),整个管道就会被拆除 (?)。为什么script.sh不继续了?

其次,当我向整个进程组发送 USR2 信号(类似于kill USR2 -$!)时,显然会发生同样的情况,因为grep退出速度很快,它会破坏整个管道而不让script.sh执行signalHandler …

pipe signals

2
推荐指数
1
解决办法
2780
查看次数

如何抑制文件重定向错误

如何抑制以下错误

if true </dev/tty 2>/dev/null; then
   read -r "$VARIABLE" </dev/tty
fi
Run Code Online (Sandbox Code Playgroud)

似乎没有忽略错误can't open /dev/tty: No such device or address。这就是整个 if 子句的目的。错误发生在if ...

shell

2
推荐指数
1
解决办法
62
查看次数

标签 统计

signals ×2

bash ×1

exit ×1

pipe ×1

process ×1

shell ×1