我需要开始一个过程,让我们说foo.我想看到stdout / stderr正常,但grep stderr的字符串栏.一旦找到酒吧
stderr foo应该被杀死.
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; })
好老式的噩梦燃料.这里发生了什么
>最外面的括号把整个东西放在一个子壳中;这限制了变量的范围,用于hygeine的目的
>我们创建一个临时文件,使用与GNU和BSD mktemp兼容的语法,并将其称为PIDFILE
>我们设置了一个全部出口陷阱(当最外层的子shell退出时运行),以删除由PIDFILE命名的文件,再次为hygeine
我们跑foo这是在复合语句中完成的,以便&绑定到foo而不是整个前面的管道
>我们将foo的标准错误重定向到等待栏出现的进程替换,然后杀死foo(其中更多的是)
>我们将foo的PID捕获到一个变量中,写入由PIDFILE命名的文件,然后等待它,这样整个命令等待foo退出; ||当这种情况发生时,true会丢弃foo的错误退出状态.
进程替换中的代码工作如下:
>首先,输入(foo的标准错误),将三通的标准输出重定向到标准错误,以便foo的标准错误确实出现在标准错误
>将输入的副本发送到另一个进程替换的文件(a process substitution within a process substitution)>在更深层次的过程替换中,首先在输入中运行grep -q,查找指定的模式,一旦找到它(或到达流的末尾)就退出,而不打印任何东西,之后(如果它找到字符串并退出成功)shell继续…>在PIDFILE命名的文件(即foo)中捕获PID被捕获的进程