SIGQUIT 中断管道

SIGQUIT 中断管道

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

这次发送SIGQUITCtrl+ \)会破坏管道:

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是使流程执行以下操作:

  1. 创建核心转储
  2. 终止

但是SIGQUIT可以处理和忽略,这ping是这样做的!从而SIGQUIT导致ping打印简短的统计信息而不终止实际过程。

使用Ctrl+\您将同时向命令的两侧发送SIGQUIT。第二部分不处理信号,并且行为符合预期!创建核心转储,然后终止,最终导致管道损坏。

因此,你应该自己处理信号:

ping 1.1.1.1 | (oq() { echo 'wait'; }; trap oq QUIT; while read i; do echo $i; done)

相关内容