1

cmd1 | 命令2

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

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

cmd2 接收 cmd1 的输出并自己进行一些处理,然后将其输出到文件中。它可以选择在写入指定数量的字节后终止。

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

这可能需要很长时间并且会减慢我的 shell 脚本。


我在做什么的具体解释:

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

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

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

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

我希望 dumpcap 生成 10 x 1G 文件然后终止。它会这样做,但 buildpcap 会持续运行很长一段时间

我使用的实际命令如下:

buildpcap --feed 3 --start-datetimed $start --end-datetime $end --stdout | dumpcap -i - -w ./tmp.pcap -a 文件:10 -b 文件大小:10000000

我希望这是有道理的。

4

2 回答 2

2

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

find / -type f | less

并从第二个窗口“pkill less”我的查找终止。

编辑:

对此答案发表评论并将其与答案整合:

在那种情况下,我猜你需要一个“看门狗脚本”来监视 cmd2 的进程状态并在 cmd2 终止时杀死 cmd1 。就像是

watch -n 5 'pgrep cmd2 || pkill cmd1'

应该做。它将每秒钟检查一次 cmd2 并在 2 消失时终止 cmd1。

于 2013-05-30T23:30:34.400 回答
1

如果在退出cmd1后尝试写入管道cmd2,它将收到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 重定向其输入。您不是直接通过管道cmd1传递到cmd2,而是通过命名文件(因此,fifo 的备用名称)间接完成了此操作。一旦cmd2退出,该kill命令也将被执行以停止cmd1

如果需要,您也可以在后台运行cmd2以下命令。kill

{ cmd2 < cmd1-to-cmd2; kill $cmd1PID; } &
于 2013-05-31T13:16:46.740 回答