1

I learned from https://unix.stackexchange.com/a/230568/674 thatping will exit with 0 after receiving SIGINT, which allows a bash script containing a ping command to continue running instead of exiting.

I have a script with similar behavior:

#!/bin/bash                                                                                                                                                                       

while true; do
    sudo -S sleep 4;
    echo $?
    sudo -k;
done

When I run it, I type Ctrl-C when it asks me for password, and the script doesn't exit, but continue running. The only difference is that sudo upon receiving SIGINT exits with 1 not 0. So I wonder why the bash script doesn't exit but continue running? Thanks.

$ ./test.sh 
[sudo] password for t: 
1
[sudo] password for t: 
1
[sudo] password for t: 
1
...
1

The test isn't a simple "did the command succeed" test. When a process exits with SIGINT, its exit status can be read by wait(2). By using WIFSIGNALED and WTERMSIG, bash can tell whether the child process (in this case, sudo) was killed directly by the signal or not.

Here's the result of that system call when hitting Ctrl+C in cat (according to strace):

wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGINT}], 0, NULL) = 9357

And here's the result when hitting Ctrl+C in sudo -S sleep 4:

wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 9479

Just for completeness, here's the result from Ctrl+C'ing ping localhost:

wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 9710
  • Thanks. Could you explain what the three lines of strace output mean? – Tim Nov 1 '18 at 0:52
  • The important bit is the section inside the square brackets. In the first case, it's telling the caller that the process died directly by the SIGINT signal. In the other cases, it's telling the caller that the process died by exiting, with statuses 1 and 0 respectively. – Joseph Sible Nov 1 '18 at 0:53
  • this absolutely does not explain why the bash script does not terminate itself upon receiving a SIGINT, but continues running the loop (in fact, if the script will terminate if it is run with dash or zsh instead of bash or ksh). I remember a discussion that was detailing the differences between shells in this regard, but I suck at googling and the only thing I could find is this which is explaining it as if it were the obvious, expected behavior. – mosvy Nov 1 '18 at 10:48

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.