我的bash脚本中有两个程序:
program1 | program2
问题是program2可能会崩溃,我想确保当它发生时,program1也将结束。我试图用
杀死program2来测试这个pkill program2
在执行期间,但program1继续运行。
据我了解,很多人都在问如何让program1继续运行,因为它默认被杀死了。我错过了什么吗?
答案 0 :(得分:3)
使用命名管道代替使用匿名管道,使您可以更好地控制每一端。
mkfifo p
program1 > p & p1_pid=$!
program2 < p
kill "$p1_pid"
在此代码段中,我们创建了一个名为p
的命名管道,然后在后台运行program1
,其标准输出重定向到p
。 p1_pid
存储program1
的进程ID以供日后使用。请注意,program1
已启动,但会立即阻止,直到某些内容打开p for eading. We run
program2 with its standard input redirected from
p`,然后在运行时阻止。
当program2
因任何原因退出时,kill
命令会将SIGTERM
发送到program1
以在必要时将其删除。这有两个好处:
它可以更快地杀死program1
,因为您不必等待program1
写入管道并收到SIGPIPE
信号。
如果program1
正在处理SIGPIPE
,它也可能正在处理其他信号。您可以使用kill
发送任何必要的信号(包括SIGKILL
,如果确实必要),以终止此过程。
答案 1 :(得分:0)
这个怎么样:
program1 | program2
rc="$?"; if [ "$rc" -ne 0 ]; then killall program1 > /dev/null 2>&1; fi
如果以上操作不起作用,您可以尝试添加
set -o pipefail
到脚本的开头。该命令将退出一个管道,其中一个步骤失败,并返回第一个失败脚本的返回码。