Consigo fazer ping no google.com por vários segundos e quando pressiono Ctrl+ C, um breve resumo é exibido na parte inferior:
$ 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
No entanto, quando faço a mesma saída de redirecionamento para o arquivo de log com tee
, o resumo não é exibido:
$ 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
Posso obter o resumo também ao redirecionar a saída com tee
?
ping
mostra o resumo quando é morto comSIGINT
, por exemplo , como resultado de CtrlC, ou quando transmitiu o número de pacotes solicitados (a-c
opção). CtrlCfazSIGINT
com que seja enviado para todos os processos do grupo de processos em primeiro plano, ou seja , neste cenário todos os processos no pipeline (ping
etee
).tee
não pegaSIGINT
(no Linux, vejaSigCgt
em/proc/$(pgrep tee)/status
), então quando recebe o sinal, ele morre, fechando sua extremidade do tubo. O que acontece a seguir é uma corrida: seping
ainda estava produzindo, ele morreráSIGPIPE
antes de receber oSIGINT
; se ele obtiver oSIGINT
antes de produzir qualquer coisa, ele tentará produzir seu resumo e morrer comSIGPIPE
. De qualquer forma, não há mais para onde ir a saída.Para obter o resumo, organize matar apenas
ping
comSIGINT
:ou execute-o com um número pré-determinado de pacotes:
ou (mantendo o melhor para o final), ignore
tee
,SIGINT
como você descobriu.Acontece que existe uma opção
tee
para ignorar os sinais de interrupção que são enviados quando CTRL+ Cé pressionado. De homem tee :Quando todo o pipeline é interrompido por
SIGINT
, este sinal é enviado para todos os processos no pipeline. O problema é quetee
geralmente está recebendoSIGINT
antesping
e depois matandoping
comSIGPIPE
. SeSIGINT
for ignorado emtee
, será entregue apenas paraping
e o resumo será exibido:Portanto , o
ping
recebimentoSIGINT
terminará eventualmente, fazendotee
com que o gravador de pipe tenha morrido, eventualmente causandotee
o término também (depois de ter "digerido" a entrada até agora).