我的 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
更好。