我正在运行这样的模拟
./waf --run scratch/myfile | awk -f filter.awk
如果waf
检测到发生了某些事情(例如,在读取特定行之后),我该如何终止filter.awk
命令?
我无法更改waf
或myfile
。我只能更改filter.awk
和上面的命令(显然)。
评论后更新:
waf
后,SIGPIPE
没有终止(因为它应该?)这是my own answer (和挑战)。
在研究了@theotherguy的ans @ Chris的答案后,我简化了一下并得到了这个:
tmp=$(mktemp)
{ ./waf --run scratch/myfile & echo $! > "$tmp"; } | { awk -f filter.awk; pkill -P $(<$tmp); kill $(<$tmp); }
不幸的是我无法摆脱tmp
文件,每次尝试将PID
作为变量传递失败。
我不会更改已接受的答案(因为它是真正需要时有效的那个),但对于任何可以简化更多的人来说都是+1。
答案 0 :(得分:4)
使用awk
的{{1}}声明。连接到exit
的管道关闭后,waf
应立即退出。
答案 1 :(得分:2)
令人困惑的是waf
因管道断裂而没有退出而导致行为不端,并且它产生了我们也必须摆脱的第二个过程:
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
将正确退出,从而允许管道完成。 waf
已生成的所有进程(通过父PID)waf
本身。答案 2 :(得分:1)
当awk
退出时,waf
在下次尝试写输出时会获得SIGPIPE
,这会导致它退出,除非写waf
的任何人故意设置它忽略SIGPIPE
告诉它退出,在这种情况下你必须用kill
或其他一些手动杀死它。类似的东西:
./waf --run scratch/myfile | ( awk -f filter.awk; killall waf )
如果-KILL
忽略所有退出信号,则killall
可能需要waf
个选项。