有什么方法可以计算非终止输入源的行数吗?例如,我想运行以下一段时间来统计请求数:
ngrep -W byline port 80 and dst host 1.2.3.4 | grep ":80" | wc
显然,这是行不通的。当我Ctrl杀死C它时,我不会从 得到任何输出wc
。如果可以的话,我宁愿避免创建文件。
答案1
从终端键入Ctrl+会发送到前台进程组。如果您想在该事件中幸存并产生输出,则需要让它忽略该信号。CSIGINT
wc
解决方案是在子 shell 中运行wc
,并在运行之前将其父 shell 设置SIGINT
为忽略wc
。 wc
将继承此设置并且在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分钟后停止正在运行的程序并继续?