我要说,我需要开始一个过程foo.我想看到stdout/stderr正常,但是grep字符串的stderr bar.一旦bar发现stderr foo应该被杀死.
这可能吗?
我最初写了一个方法来做这个涉及流调配,但它不是很好.一些评论与该版本有关.如果你好奇,请检查历史.
这是一种方法:
(PIDFILE=$(mktemp /tmp/foo.XXXXXX) && trap "rm $PIDFILE" 0 \
&& { foo \
2> >(tee >(grep -q bar && kill $(cat $PIDFILE)) >&2) \
& PID=$! && echo $PID >$PIDFILE ; wait $PID || true; })
Run Code Online (Sandbox Code Playgroud)
好老式的噩梦燃料.这里发生了什么事?
mktemp,然后调用它PIDFILEPIDFILE,同样用于hygeinefoo; 这是在复合语句中完成的,以便&绑定到foo整个前面的管道而不是绑定到整个前面的管道foo标准错误重定向到一个等待bar出现然后杀死的进程替换foo(后来更多)fooPID 捕获到变量中,将其写入命名的文件PIDFILE,然后等待它,以便整个命令在foo退出之前等待退出; 该|| true丢弃的错误退出状态foo当这种情况发生.进程替换中的代码如下:
tee输入(foo标准错误),将tee标准输出重定向到标准错误,因此foo标准错误确实出现标准错误grep -q在输入上运行,该输入查找指定的模式,并在找到它时立即退出(或者当它到达流的末尾时),而不打印任何内容,之后(如果它找到了字符串并退出成功)shell继续...kill在其命名的文件中捕获PID的进程PIDFILE,即foo小智 5
汤姆安德森的答案非常好,但kill $(cat $PIDFILE)只有在我自己的系统foo上或通过Ctrl-C终止时才会发生.以下解决方案适合我
while read g
do
if [[ $g =~ bar ]]
then
kill $!
fi
done < <(
exec foo 2> >(tee /dev/tty)
)
Run Code Online (Sandbox Code Playgroud)