I'm trying to figure out why this doesn't work:
#!/bin/bash
sudo sleep 60 &
sudo_pid=$!
sudo kill $sudo_pid
I'd expect that after the kill
, the sudo
command and its child sleep
process would be terminated, but they aren't, as shown by this script:
#!/bin/bash
sudo sleep 60 &
sudo_pid=$!
sudo kill $sudo_pid
if ps -p $sudo_pid > /dev/null; then
sudo kill $sudo_pid
else
echo "No sudo process running"
exit 1
fi
if ps -p $sudo_pid > /dev/null; then
echo "sudo (pid $sudo_pid) is still running"
ps -F $sudo_pid
else
echo "sudo successfully killed"
fi
Which yields this output when I run it (with sudo
creds cached):
jon@ubuntu:~$ ./so.sh
sudo (pid 46199) is still running
UID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD
root 46199 46198 0 14764 3984 3 13:37 pts/0 S+ 0:00 sudo sleep 60
After the script completes (and sudo sleep 60
is still running), it is possible to kill it with the identical command:
jon@ubuntu:~$ ps -F 46199
UID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD
root 46199 1 0 14764 3984 3 13:37 pts/0 S 0:00 sudo sleep 60
jon@ubuntu:~$ sudo kill 46199
jon@ubuntu:~$ ps -F 46199
UID PID PPID C SZ RSS PSR STIME TTY STAT TIME CMD
jon@ubuntu:~$
I notice that after the so.sh
script exits, the parent process ID for sudo sleep 60
has changed from the script to the init
process, which I think is significant. It's also possible to successfully kill the sudo sleep 60
process from a different shell while the so.sh
script is still running.
I also noticed that using sudo kill -ABRT
in the script (as opposed to kill
's default SIGTERM
) does successfully kill the sudo
process, so I assume that is has something to do with the way sudo
handles SIGTERM
. However, based on the man page, I don't think it should be doing anything special:
Signal handling
When the command is run as a child of the sudo process, sudo will relay
signals it receives to the command. The SIGINT and SIGQUIT signals are
only relayed when the command is being run in a new pty or when the sig‐
nal was sent by a user process, not the kernel. This prevents the com‐
mand from receiving SIGINT twice each time the user enters control-C.
The only special handling of SIGTERM
mentioned in the man page is for signals that were sent by the command it is running
; not the case here. Furthermore, I changed the ps -F
in above script to ps -o blocked,caught,ignored,pending
and it output
sudo (pid 46429) is still running
BLOCKED CAUGHT IGNORED PENDING
0000000000000000 00000001800b7a07 0000000000000000 0000000000000000
Which seems to indicate that SIGTERM isn't being blocked or ignored, so why isn't the sudo sleep 60
process getting terminated?
I've come up with several workarounds (setsid
, sudo -b
, killing the child sleep
process rather than the parent sudo
process), so I'm not looking for alternate approach answers. I just want to understand what's going on here.
In case it matters:
jon@ubuntu:~$ uname -a
Linux ubuntu 4.13.0-16-generic #19-Ubuntu SMP Wed Oct 11 18:35:14 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
jon@ubuntu:~$ sudo --version
Sudo version 1.8.20p2
Sudoers policy plugin version 1.8.20p2
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.20p2