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
我希望这是有道理的。
答案 0 :(得分:2)
这在很大程度上取决于cmd1是谁/什么,以及实施的干净程度。例如,如果我这样做
find / -type f | less
从第二个窗口" pkill less"我的发现终止了。
编辑:
对此答案进行评论并将其与答案相结合:
在这种情况下,我猜你需要一个"看门狗脚本"监视cmd2的进程状态并在cmd2终止时终止cmd1。像
这样的东西watch -n 5 'pgrep cmd2 || pkill cmd1'
应该这样做。它将每秒检查cmd2,如果2消失则杀死cmd1。
答案 1 :(得分: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重定向其输入。您可以通过命名文件(因此,fifo的替代名称)间接地将cmd1
直接传递给cmd2
,而不是将cmd2
直接传递给kill
。退出cmd1
后,将执行cmd2
命令以停止kill
。
如果需要,您也可以在后台运行{ cmd2 < cmd1-to-cmd2; kill $cmd1PID; } &
和以下{{1}}。
{{1}}