终止管道中的上一个命令

终止管道中的上一个命令

本文介绍了终止管道中的上一个命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行这样的仿真

./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)?

我无法更改wafmyfile.我只能更改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 receiving SIGPIPE (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 run waf 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, since cat 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.
    • 这篇关于终止管道中的上一个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 15:44