尝试仅捕获ping
输出中的数据包返回时间,我发出
$ ping 192.168.0.1 | grep -o '[^ =]* ms'
它起作用了,显示每个数据包到达的时间。由于我也想摆脱时间单位,认为这就足够了:
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
但是,令我惊讶的是,它挂起,没有显示任何输出。然而,用输出echo
中的示例行替换第一个命令ping
可以按预期工作(它输出5.07
):
$ echo '64 bytes from 192.168.0.1: icmp_seq=10 ttl=64 time=5.07 ms' | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
我找到了其他方法来仅获取没有毫秒单位的时间,但仍然:ping
命令有什么问题?为什么通过一根管道可以,但通过两根管道就不行?
PS:下面的这些也失败了,而他们的echo
版本成功了,因此问题不可能出在grep
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | sed 's_ ms__'
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | cut -f 1 -d ' '
$ ping 192.168.0.1 | cut -f 7 -d ' ' | cut -f 2 -d '='
答案1
确定的答案是行缓冲。您可以使用ping -c 3
而不是仅使用 来演示这一点ping
,其中所有输出仅在第一个命令完成时生成。
作为 GNU 的一种解决方法,grep
您可以将两个过滤器减少为一个
ping 192.168.0.1 | grep -oP '[[:digit:].]+(?= ms)'
或者,如果您确实想使用两个过滤器,则grep --line-buffered ...
或stdbuf -oL grep ...
都适合您。
答案2
我认为您的问题是由 shell 的行缓冲引起的。
如果您让命令运行足够长的时间,您应该会看到一些输出。
或者像这样限制 ping 数量:
$ ping -c4 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'
如果您遵循此操作,则会有更多信息和解决方法(解决方案?)关联