管道命令挂在被杀死的熟睡的孩子身上

管道命令挂在被杀死的熟睡的孩子身上

如果某个命令挂起,我使用“看门狗”功能来执行故障安全唤醒。这是通过运行一个休眠 30 秒然后执行唤醒的后台任务来实现的。如果父命令在超时期限之前成功,脚本将终止看门狗。

当管道函数(例如sed格式化其输出)时,即使kill在后台任务上调用之后,它也会在睡眠期间挂起。是什么赋予了?

这是一个 MCVE:

#! /bin/bash

function indent () { "$@" 2>&1 | sed 's/^/    /'; }

function sleeper () { sleep 1 && echo "Sleep complete."; }

function child () {
        sleeper &
        # ... do something that might hang here ...
        local spid=$!                                                                                                           echo "Invoked sleeper." | grep "sleep"
        kill $spid                                                                                                              
        echo "Done child."
}

indent child

即使睡眠者已经被杀死,该进程也会睡眠一秒钟。

答案1

稍微修改一下,杀死sleep父 PID 为 的进程$spid

#! /bin/bash

function indent () { "$@" | sed 's/^/    /'; }

function sleeper () { sleep 1 && echo "Sleep complete."; }

function child () {
        sleeper &
        local spid=$!
        echo "Invoked sleeper." | grep "sleep"
        pkill -P "$spid" sleep
        echo "Done child."
}

indent child

我认为问题在于后台作业在运行时sleep实际上不会收到TERM您发送的信号,直到sleep终止为止。上面的pkill命令将向进程发出信号sleep,而不是向后台作业本身发出信号。

相关内容