![当生成的程序打印出特定警告时,中止该程序](https://linux22.com/image/1543987/%E5%BD%93%E7%94%9F%E6%88%90%E7%9A%84%E7%A8%8B%E5%BA%8F%E6%89%93%E5%8D%B0%E5%87%BA%E7%89%B9%E5%AE%9A%E8%AD%A6%E5%91%8A%E6%97%B6%EF%BC%8C%E4%B8%AD%E6%AD%A2%E8%AF%A5%E7%A8%8B%E5%BA%8F.png)
我的 Bash 4 脚本调用第三方程序P
(我无法重新编译的程序),该程序将警告打印到 STDOUT。当它打印时yikes
,它也会进入无限循环。那么当我检测到时yikes
,我该如何立即停止P
并将控制权返回给我的脚本?(否则让其P
正常完成。)
可能有用的片段:
(echo $BASHPID > /tmp/subpid; ./P | tee /tmp/Pout ) &
tail -f /tmp/Pout | grep -m1 yikes && kill -9 $(cat /tmp/subpid)
wait
答案1
使用expect
:
P | { expect -c 'expect -timeout -1 yikes' && killall P ; }
这种用法可能不是最佳的,但仍然expect
是适合这项工作的正确工具。
如果P
之后打印更多内容yikes
,它会注意到管道破裂,因此killall
不需要:
P | expect -c 'expect -timeout -1 yikes'
答案2
coproc ./P
grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
演示:
coproc { sleep 1; echo yikes; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
coproc { sleep 1; echo zzzzz; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
发现于https://stackoverflow.com/a/26779617/2097284。
然而,https://unix.stackexchange.com/questions/86270/how-do-you-use-the-command-coproc-in-bash解释了为什么命名管道更好(尽管这里不可能发生死锁),以及为什么expect
更好。