当右侧终止时,使管道的左侧终止

时间:2013-05-30 23:24:06

标签: linux shell pipe

cmd1 | CMD2

当管道的接收命令终止时,如何才能使管道的发送命令终止?

cmd1处理文件中的数据,其输出通过管道传输到cmd2。

cmd2接收cmd1的输出并执行自己的一些处理,输出到文件。它有一个选项,可以在写入指定数量的字节后终止。

我遇到的问题是cmd1继续执行,直到它处理了正在处理的文件中的所有数据,即使cmd2已经终止。

这可能需要很长时间并且会降低我的shell脚本速度。


我正在做的具体解释:

“超级代理”网络探测设备正在捕获流量并将其存储在6小时环形缓冲区中的文件中。这些是某种格式或其他格式的原始捕获文件。专有命令可用于根据时间范围构建pcap文件。这是上面的cmd1,称为“buildpcap”

6小时的流量可以生成一个非常大(200GB +)的文件。

我想将总pcap限制为10GB并将其拆分为1GB文件部分。

我不能限制文件大小的输出,也不能使用buildpcap拆分成多个部分文件,但我可以输出到stdout而不是file,并将其传递给可以执行的命令;在这种情况下,wireshark的dumpcap,从上面是cmd2。

我想让dumpcap生成10个1G文件,然后终止。它可以做到这一点,但buildpcap持续运行了相当长的时间

我正在使用的实际命令如下:

buildpcap --feed 3 --start-datetimed $ start --end-datetime $ end --stdout | dumpcap -i - -w ./tmp.pcap -a files:10 -b filesize:10000000

我希望这是有道理的。

2 个答案:

答案 0 :(得分:2)

这在很大程度上取决于cmd1是谁/什么,以及实施的干净程度。例如,如果我这样做

find / -type f | less

从第二个窗口" pkill less"我的发现终止了。

编辑:

对此答案进行评论并将其与答案相结合:

在这种情况下,我猜你需要一个"看门狗脚本"监视cmd2的进程状态并在cmd2终止时终止cmd1。像

这样的东西
watch -n 5 'pgrep cmd2 || pkill cmd1'

应该这样做。它将每秒检查cmd2,如果2消失则杀死cmd1。

答案 1 :(得分:1)

如果cmd1cmd2退出后尝试写入管道,则会收到SIGPIPE信号。默认响应是退出(尽管可能cmd1被写入以不同方式处理信号)。

但是,如果cmd1忙于做其他事情并且不尝试写入管道,则不会通知cmd2退出。这是一个解决方法:

mkfifo cmd1-to-cmd2
cmd1 > cmd1-to-cmd2 & cmd1PID=$!
cmd2 < cmd1-to-cmd2; kill $cmd1PID

首先,创建一个fifo(先进先出)文件(也称为命名管道)。接下来,在后台运行cmd1,将其输出重定向到fifo。记住它的进程ID。运行cmd2,从fifo重定向其输入。您可以通过命名文件(因此,fifo的替代名称)间接地将cmd1直接传递给cmd2,而不是将cmd2直接传递给kill。退出cmd1后,将执行cmd2命令以停止kill

如果需要,您也可以在后台运行{ cmd2 < cmd1-to-cmd2; kill $cmd1PID; } & 和以下{{1}}。

{{1}}