我可以 ping google.com几秒钟,当我按Ctrl+C时,底部会显示一个简短的摘要:
$ ping google.com
PING google.com (74.125.131.113) 56(84) bytes of data.
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=2 ttl=56 time=46.7 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=3 ttl=56 time=45.0 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=4 ttl=56 time=54.5 ms
^C
--- google.com ping statistics ---
4 packets transmitted, 3 received, 25% packet loss, time 3009ms
rtt min/avg/max/mdev = 44.965/48.719/54.524/4.163 ms
但是,当我使用 将相同的重定向输出重定向到日志文件时tee
,不会显示摘要:
$ ping google.com | tee log
PING google.com (74.125.131.113) 56(84) bytes of data.
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=1 ttl=56 time=34.1 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=2 ttl=56 time=57.0 ms
64 bytes from lu-in-f113.1e100.net (74.125.131.113): icmp_seq=3 ttl=57 time=50.9 ms
^C
使用 重定向输出时,我也可以获得摘要tee
吗?
ping
当它被 杀死时显示摘要SIGINT
,例如作为 的结果CtrlC,或者当它已经传输了请求数量的数据包(-c
选项)。CtrlC导致SIGINT
被发送到前台进程组中的所有进程,即在这种情况下,管道中的所有进程(ping
和tee
)。tee
没有捕捉SIGINT
到(在 Linux 上,查看SigCgt
in/proc/$(pgrep tee)/status
),所以当它接收到信号时,它会死掉,关闭管道的末端。接下来发生的是一场比赛:如果ping
仍在输出,它将SIGPIPE
在获得SIGINT
;之前死亡。如果它SIGINT
在输出任何东西之前得到了,它会尝试输出它的摘要并死掉SIGPIPE
. 在任何情况下,输出都无处可去。要获得摘要,请安排仅
ping
使用以下命令杀死SIGINT
:或使用预定数量的数据包运行它:
或(将最好的保留在最后),如您所见,
tee
忽略。SIGINT
事实证明,有一个选项可以忽略按下+
tee
时发送的中断信号。来自man tee:CTRLC当整个管道被 中断时
SIGINT
,该信号被发送到管道中的所有进程。问题是tee
通常是SIGINT
先接收ping
然后ping
用SIGPIPE
. 如果SIGINT
在 中被忽略tee
,它只会被传递到ping
并显示摘要:因此
ping
接收SIGINT
最终将终止,导致tee
看到管道编写器已经死亡,最终也导致tee
终止(在到目前为止“消化”输入之后)。