Linux ping 实用程序可以在SIGQUIT
不终止的情况下生成一些接收统计信息。它看起来像这样:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=37.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=45 time=36.3 ms
2/2 packets, 0% loss, min/avg/ewma/max = 36.399/37.126/37.672/37.854 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=45 time=36.2 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 36.294/36.849/37.854/0.711 ms
正如您所看到的,我SIGQUIT
在第二次请求后立即按下Ctrl+发送\并立即获得了统计数据。
但是当我尝试使用 ping 和管道时,情况就不同了。命令:
ping -O 8.8.8.8 | while read pong; do echo "$(date): $pong"; done
这次发送SIGQUIT
(Ctrl+ \)会破坏管道:
Tue Jul 30 18:15:20 EEST 2019: PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
Tue Jul 30 18:15:20 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=71.1 ms
Tue Jul 30 18:15:21 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=2 ttl=45 time=51.4 ms
Tue Jul 30 18:15:22 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=3 ttl=45 time=54.5 ms
Tue Jul 30 18:15:23 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=4 ttl=45 time=56.5 ms
Tue Jul 30 18:15:24 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=5 ttl=45 time=56.5 ms
Tue Jul 30 18:15:25 EEST 2019: 64 bytes from 8.8.8.8: icmp_seq=6 ttl=45 time=60.1 ms
6/6 packets, 0% loss, min/avg/ewma/max = 51.421/58.394/63.927/71.104 ms
Quit (core dumped)
有人能告诉我这种行为的原因是什么吗?
答案1
发送时的默认行为SIGQUIT
是使流程执行以下操作:
- 创建核心转储
- 终止
但是SIGQUIT
可以处理和忽略,这ping
是这样做的!从而SIGQUIT
导致ping
打印简短的统计信息而不终止实际过程。
使用Ctrl+\您将同时向命令的两侧发送SIGQUIT
。第二部分不处理信号,并且行为符合预期!创建核心转储,然后终止,最终导致管道损坏。
因此,你应该自己处理信号:
ping 1.1.1.1 | (oq() { echo 'wait'; }; trap oq QUIT; while read i; do echo $i; done)