计算非终止输入的行数

计算非终止输入的行数

有什么方法可以计算非终止输入源的行数吗?例如,我想运行以下一段时间来统计请求数:

ngrep -W byline port 80 and dst host 1.2.3.4 | grep ":80" | wc

显然,这是行不通的。当我Ctrl杀死C它时,我不会从 得到任何输出wc。如果可以的话,我宁愿避免创建文件。

答案1

从终端键入Ctrl+会发送到前台进程组。如果您想在该事件中幸存并产生输出,则需要让它忽略该信号。CSIGINTwc

解决方案是在子 shell 中运行wc,并在运行之前将其父 shell 设置SIGINT为忽略wcwc将继承此设置并且在SIGINT发送到进程组时不会死亡。管道的其余部分将消失,只wc从另一端没有进程的管道中进行读取。这将导致wc查看EOF管道,然后输出其计数并退出。

ngrep -W byline port 80 and dst host 1.2.3.4 | grep ":80" | (trap '' INT ; wc)

答案2

以下是在读取当前计数后继续计数的方法:

我的非终止测试输入源是 ping:

$ ping 127.0.0.1  
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.041 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.025 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.045 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.032 ms
64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.030 ms
^C

使用其他解决方案时,我们必须决定何时读出行数,并中断正在运行的命令。
但理想情况下我们只想知道当前的行数,对吧?

那么,为什么不直接计算行数呢?适合这项工作的工具是nl,在每行前面添加当前计数:

$ ping 127.0.0.1 | nl
     1  PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
     2  64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.040 ms
     3  64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.022 ms
     4  64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.025 ms
     5  64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.021 ms
     6  64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.022 ms
     7  64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.022 ms
     8  64 bytes from 127.0.0.1: icmp_seq=7 ttl=64 time=0.021 ms
     9  64 bytes from 127.0.0.1: icmp_seq=8 ttl=64 time=0.029 ms
^C

答案3

您可以使用:

$ ngrep -W byline port 80 and dst host 1.2.3.4 | grep ":80" |
perl -nle 'system("clear");print $.'

perl将跟踪您有哪些行,在打印之前清除旧输出。

答案4

如果您愿意指定时间限制(而不是即兴执行),您可以使用此技巧

( cmdpid=$BASHPID; (sleep 300; Kill $cmdpid) & exec ngrep(ngrep 参数)) | grep ":80" |厕所

受到启发这个答案最近关于 SU 的一个问题;本质上如何在5分钟后停止正在运行的程序并继续?

相关内容