问题描述
我正在运行这样的仿真
./waf --run scratch/myfile | awk -f filter.awk
一旦filter.awk
检测到发生了什么事情(例如在读取特定行之后),我如何杀死waf
命令?
How can I kill the waf
command as soon as filter.awk
detects that something happened (e.g. after a specific line is read)?
我无法更改waf
或myfile
.我只能更改filter.awk
和上面的命令(显然).
I cannot change waf
or myfile
. I can only change filter.awk
, and the above command (obviously).
评论后更新:
Update after comments:
-
waf
在收到SIGPIPE
之后没有终止(应该吗?) - 它产生需要清理的子进程.
waf
does not terminated after receivingSIGPIPE
(as it should?)- It spawns child processes, that need cleaning up.
这是我自己的答案 (和挑战).
在处理完@thatotherguy的回答@Chris的答案之后,我做了一些简化,得到了:
After working on @thatotherguy's ans @Chris's answers, I simplified a bit and got this:
tmp=$(mktemp)
{ ./waf --run scratch/myfile & echo $! > "$tmp"; } | { awk -f filter.awk; pkill -P $(<$tmp); kill $(<$tmp); }
不幸的是,我无法摆脱tmp
文件,每次将PID
作为变量传递的尝试都失败了.
Unfortunately I could not get rid of the tmp
file, every attempt to pass the PID
as a variable failed.
我不会更改已接受的答案(因为它是真正需要时才起作用的答案),但是对于可以简化更多内容的人来说,则为+1.
I won't change the accepted answer (since it was the one that worked when it was really needed), but +1 for anyone that can simplify more.
推荐答案
之所以如此棘手,是因为waf
行为异常,因为在管道中断时不退出,它产生了第二个进程,我们也必须摆脱它:
What makes this tricky is that waf
misbehaves by not exiting when the pipe breaks, and it spawns off a second process that we also have to get rid off:
tmp=$(mktemp)
cat <(./waf --run scratch/myfile & echo $! > "$tmp"; wait) | awk -f filter.awk;
pkill -P $(<$tmp)
kill $(<$tmp)
- 我们使用
<(process substitution)
在后台运行waf
并将其pid写入临时文件. - 我们使用
cat
作为中介将数据从此过程中继到awk,因为在管道破裂时cat
会正确退出,从而允许管道完成. - 完成管道后,我们将杀死所有由父PID生成的
waf
进程. - 最后,我们杀死了
waf
本身. - We use
<(process substitution)
to runwaf
in the background and write its pid to a temp file. - We use
cat
as an intermediary to relay data from this process to awk, sincecat
will exit properly when the pipe is broken, allowing the pipeline to finish. - When the pipeline's done, we kill all processes that
waf
has spawned (by Parent PID) - Finally we kill
waf
itself.
这篇关于终止管道中的上一个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!