X-posting from unix.SE on recommendation.
I have a bash script called testing
saved within /usr/local/bin
.
In one Terminal window in macOS I run sudo testing
. In a second terminal window, I generate a list of processes:
ps -axo tty,pid,ppid,args | { head -1; grep "bash\|testing" | grep -v grep; }
Which returns as expected:
TTY PID PPID ARGS
ttys000 73674 73673 -bash # login shell used to run sudo
ttys000 73701 73674 sudo testing # sudo process
ttys000 73702 73701 /bin/bash /usr/local/bin/testing # "testing" bash script being run by sudo
ttys001 3714 3713 -bash # second login shell used to generate this process list
However, after quitting the first Terminal window (while testing
is still running within it), the process list looks like this:
TTY PID PPID ARGS
?? 73701 1 sudo testing
?? 73702 73701 /bin/bash /usr/local/bin/testing
ttys001 3714 3713 -bash
As expected, the first login shell has been terminated and the second login shell is still running. But the sudo process and its forked (now-orphaned) child, the testing
script, are still running!
I suspect this is because the user, not root, is the one closing the Terminal window, and as such does not have the necessary permissions to affect root processes. Is this correct? I feel like I'm missing something basic here. Is there some way to allow the root processes to be terminated by closing the Terminal window?
Best Answer
You are talking about orphan processes. As you will see, your question has little to do with
sudo
. Orphans are assigned to process 1. This process 1 is calledinit
and is a daemon process that continues running until the system is shut down. Here are two simple examples where orphans are created. The macOS is High Sierra which uses bash as the default shell.When the parent windows terminates, a hang up signal (
SIGHUP
) is sent to the child processes. Normally, this causes each child processes to terminate. However, if a child chooses not to terminate or is never sent a hangup signal (SIGHUP
), then the child can become an orphan.Example 1
Open a new Terminal window and enter the command
shopt -s huponexit
. This command is necessary because bash is a login shell. Output shown below.Enter the command
{ trap '' hup; sleep 60000; } &
, as shown below.Here a new process 8993 is created as job 1. The
trap '' hup
command causes the hang up signal (SIGHUP
) to be ignored. Next, open a another Terminal window and enter the commandps -axo tty,pid,ppid,args 8993
, as shown below.This shows the first window was assigned
ttys008
and has a process id of 8972. Next, the first window is closed. In the popup window,Terminate
is selected. A hang up signal (SIGHUP
) is sent to process 8972, which is ignored. Process 8972 is now orphaned and will be assigned to process 1. Repeating theps -axo tty,pid,ppid,args 8993
command in the second window will show this. See below.Finally, the commands shown below are entered to send a terminal signal (
SIGTERM
) to process 8993 and show that the process has terminated.Example 2
This is basically the same as example 1, except instead of having the process ignore the hangup signal (
SIGHUP
), thedisown %1
command is used to prevent a hangup signal (SIGHUP
) from being sent to the process. Open a new Terminal window and enter thecommand shopt -s huponexit
. This command is necessary because bash is a login shell. Output shown below.Next, enter
sleep 60000 &
followed bydisown %1
. The%1
parameter represents job 1. The results are shown below.In the second window, enter
ps -axo tty,pid,ppid,args 9139
. The results are shown below.After closing the third window, enter
ps -axo tty,pid,ppid,args 9139
in the second window. The results are shown below. Another orphan has been created.Finally, enter
kill 9139
andps -axo tty,pid,ppid,args 9139
, as shown below.References
Orphan process
Zombie process
init
Daemon