14

When a process breaks, as I know no output will be return anymore. But always after breaking ping command we have the statistics of the execution, and as I know it's part of the output.

amirreza@time:~$ ping 4.2.2.4
PING 4.2.2.4 (4.2.2.4) 56(84) bytes of data.
64 bytes from 4.2.2.4: icmp_seq=1 ttl=51 time=95.8 ms
64 bytes from 4.2.2.4: icmp_seq=2 ttl=51 time=92.3 ms
^C
--- 4.2.2.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 92.321/94.052/95.783/1.731 ms
amirreza@time:~$ 

How does it work?

  • 17
    "When a process breaks, as I know no output will be return anymore." [citation needed] This is false. – Eric Towers Nov 9 '20 at 20:57
  • 4
    That thing you know, it just ain’t so. – Harper - Reinstate Monica Nov 11 '20 at 7:23
48

Ctrl+C makes the terminal send SIGINT to the foreground process group. A process that receives SIGINT can do anything, it can even ignore the signal. A common reaction to SIGINT is to exit gracefully, i.e. after cleaning up etc.

Your ping is simply designed to print statistics upon SIGINT and then to exit.

Other tools may not exit upon SIGINT at all. E.g. a usual behavior of an interactive shell (while not running a command) is to clear its command line and redraw the prompt.

SIGINT is not the only signal designed to terminate commands. See the manual (man 7 signal), there are many signals whose default action is to terminate the process. kill sends SIGTERM by default. SIGTERM is not SIGINT. Both can be ignored. SIGKILL cannot be caught, blocked, or ignored, but it should be your last choice.

  • 2
    @AmirrezaRiahi The default action of the SIGINT signal is to kill the process. But the process can override this default. – Barmar Nov 9 '20 at 6:12
  • 1
    @Barmar, same with SIGTERM – JoelFan Nov 9 '20 at 8:43
  • 1
    @AmirrezaRiahi if by chance your problem was not being to break out of ping when called in a bash loop, you can use awk as a wrapper: xawk(){ awk "BEGIN{system(\"$*\")}"; }; ...; while xawk ping www.google.com; do :; done => will promptly die after the first Control-C, no need to keep it pressed ;-) (I've seen this in some answer here -- but I'm not able to find it now). – user414777 Nov 9 '20 at 11:11
  • 1
    @user414777 Actually ping does obey WCE. To it, Ctrl-C is a request to perform a normal exit of the otherwise infinite loop, thus it exits with a normal status, not a signal. This causes bash to correctly continue running additional commands in a script. (Not that you would typically run ping this way in a script anyway.) – Miral Nov 9 '20 at 23:22
  • 1
    I disagree that most users should expect that. It's no different from running nano or another interactive editor and using whatever command that provides to perform a normal exit. It just so happens that in the case of ping that it uses Ctrl+C to request a normal exit, that's all. – Miral Nov 10 '20 at 22:53
4

Additional to the accepted answer - here's ping running in one session, and in another I ran different kill commands.

server~ $ ping google.com
PING google.com (172.217.5.110) 56(84) bytes of data.
64 bytes from google.com(172.217.5.110): icmp_seq=1 ttl=111 time=1.68 ms
64 bytes from google.com(172.217.5.110): icmp_seq=2 ttl=111 time=1.73 ms
Terminated

The above was a SIGTERM, which is signal 15. The exit code was 143.

server ~ $ ping google.com
PING google.com (172.217.5.110) 56(84) bytes of data.
64 bytes from google.com(172.217.5.110): icmp_seq=1 ttl=111 time=1.71 ms
64 bytes from google.com(172.217.5.110): icmp_seq=2 ttl=111 time=1.71 ms
Killed

This was a SIGKILL, which is signal 9. Visually it looks the same, but with a different text, and the exit code is 137 this time.

server~ $ ping google.com
PING google.com (172.217.5.110) 56(84) bytes of data.
64 bytes from google.com(172.217.5.110): icmp_seq=1 ttl=111 time=1.69 ms
64 bytes from google.com(172.217.5.110): icmp_seq=2 ttl=111 time=1.70 ms
           **signal sent here**
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.697/1.701/1.705/0.004 ms

This was a SIGINT which is signal 2. So functionally the same as a ^C Curiously the exit code is 0 which to most tests will be a success, as opposed to a failure.

The upshot of this is that ping does different things for different signals.

You can see a source file for ping at https://gist.github.com/kbaribeau/4495181 which references https://ftp.arl.army.mil/~mike/ping.html as the original.

line
408     signal( SIGINT, finish );
409     signal(SIGALRM, catcher);

457     *           C A T C H E R
459     * This routine causes another PING to be transmitted, and then
460     * schedules another SIGALRM for 1 second from now.

See the link for the full code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.