![对于某些 IP,请 ping -c 4 -W 1 ip | cat 在 ping 完成之前不会输出任何内容,而其他的则输出任何内容](https://linux22.com/image/35816/%E5%AF%B9%E4%BA%8E%E6%9F%90%E4%BA%9B%20IP%EF%BC%8C%E8%AF%B7%20ping%20-c%204%20-W%201%20ip%20%7C%20cat%20%E5%9C%A8%20ping%20%E5%AE%8C%E6%88%90%E4%B9%8B%E5%89%8D%E4%B8%8D%E4%BC%9A%E8%BE%93%E5%87%BA%E4%BB%BB%E4%BD%95%E5%86%85%E5%AE%B9%EF%BC%8C%E8%80%8C%E5%85%B6%E4%BB%96%E7%9A%84%E5%88%99%E8%BE%93%E5%87%BA%E4%BB%BB%E4%BD%95%E5%86%85%E5%AE%B9.png)
为什么
$ ping -c 4 -W 1 127.0.0.1 | cat
和
$ ping -c 4 -W 1 1.1.1.1
立即打印他们的输出,而
$ ping -c 4 -W 1 1.1.1.1 | cat
四秒内不打印任何内容,然后一次性打印所有输出?
注意,第一个命令打印成功的 ping,另外两个命令打印超时,正如预期的那样。
答案1
在 ping 输出到 shell 管道的情况下,不同的行为可以通过缓冲来解释。 ping 在报告每个成功接收到的回显数据包后调用 fflush(),因此这些行会立即发送到 cat,后者会立即输出它们。 ping 确实不是在写出报告超时数据包的行后调用 fflush(),因此 stdio 缓冲这些行,直到 ping 调用 exit(),然后将它们全部发送到 cat,然后由 cat 输出它们。
在 ping 直接输出到终端的情况下,您会立即看到成功和失败输出,因为默认情况下,stdio 线路将所有输出缓冲到与 ttys 关联的流。因此,每个输出行都会立即发送到终端,而不是由 stdio 缓冲。
本着授人以鱼,你可以通过阅读 OS X 来验证这一切ping 的源代码并阅读 OS Xstdio 的手册页。
答案2
我相信这是因为 cat 获取输入的方式,第一个命令给出的退出状态为 2,而正在 ping 的 IP 地址给出的退出状态为 0。
这意味着 cat 立即显示 STDOUT 的输出,而它将 STDERR 放入缓冲区,然后在命令终止时显示它。
答案3
它正在等待 DNS 或 ICMP 回显应答数据包。如果是 DNS,请尝试该-n
选项。如果不是,请尝试区分应答 ICMP 回显请求的主机和不应答 ICMP 回显请求的主机(或者其应答在途中的某处被过滤)。