为什么“ping”在重定向输出时不输出摘要?

ks1*_*322 30 linux signals ping tee

我可以 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
Run Code Online (Sandbox Code Playgroud)

但是,当我使用 执行相同的重定向输出到日志文件时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
Run Code Online (Sandbox Code Playgroud)

使用 重定向输出时也可以获得摘要吗tee

Ste*_*itt 61

ping显示当它被杀死时的摘要SIGINT例如由于CtrlC,或者当它传输了请求数量的数据包(选项-c)时。CtrlC导致SIGINT被发送到前台进程组中的所有进程,在这种情况下管道中的所有进程(pingtee)。teedoes\xe2\x80\x99t catch SIGINT(在 Linux 上,请查看SigCgt/proc/$(pgrep tee)/status,因此当它接收到信号时,它会死亡,关闭管道的末端。接下来发生的是一场竞赛:如果ping仍在输出,它将SIGPIPE在获得SIGINT;之前死亡。如果它在输出任何内容之前得到SIGINT,它将尝试输出其摘要并死于SIGPIPE。无论如何,\xe2\x80\x99s 不再有任何地方可以输出。

\n

要获得摘要,请安排仅ping使用以下命令进行杀死SIGINT

\n
killall -INT ping\n
Run Code Online (Sandbox Code Playgroud)\n

或使用预定数量的数据包运行它:

\n
ping -c 20 google.com | tee log\n
Run Code Online (Sandbox Code Playgroud)\n

或者(将最好的留到最后),忽略teeSIGINT正如您发现的那样。

\n


ks1*_*322 29

事实证明,有一个选项可以忽略按下+tee时发送的中断信号。来自男士 T 恤CTRLC

   -i, --ignore-interrupts
          ignore interrupt signals
Run Code Online (Sandbox Code Playgroud)

当整个管道被 中断时SIGINT,该信号被发送到管道中的所有进程。问题是tee通常SIGINT先接收ping然后ping用杀死SIGPIPE。如果SIGINT在 中被忽略tee,它将仅传递到ping并显示摘要:

$ ping google.com | tee --ignore-interrupts log 
PING google.com (142.250.150.101) 56(84) bytes of data.
64 bytes from la-in-f101.1e100.net (142.250.150.101): icmp_seq=1 ttl=104 time=48.8 ms
64 bytes from la-in-f101.1e100.net (142.250.150.101): icmp_seq=2 ttl=104 time=51.0 ms
64 bytes from la-in-f101.1e100.net (142.250.150.101): icmp_seq=3 ttl=107 time=32.2 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 32.198/44.005/50.973/8.394 ms
Run Code Online (Sandbox Code Playgroud)

因此ping,接收SIGINT最终将终止,导致tee看到管道编写器已经死亡,最终tee也导致终止(在“消化”输入至今之后)。