Friday, October 29, 2021

[SOLVED] Why is nohup required and disown doesn't work by itself?

Issue

Consider this snippet as being saved in a file called snippet.sh:

nohup xmessage HI </dev/null &>/dev/null & disown
sleep 3

From the same directory, do xterm -e bash snippet.sh.

After 3 seconds, the xterm should disappear while the xmessage window lingers. All good and well. But what if the nohup is removed from the command in the snippet file? Then the xmessage which disappears along with the xterm. The bash documentation seems to indicate that disown should, by itself, be sufficient to prevent SIGHUP from being sent:

       The  shell exits by default upon receipt of a SIGHUP.  Before exiting, an interactive shell resends
       the SIGHUP to all jobs, running or stopped.  Stopped jobs are sent  SIGCONT  to  ensure  that  they
       receive the SIGHUP.  To prevent the shell from sending the signal to a particular job, it should be
       removed from the jobs table with the disown builtin (see SHELL BUILTIN COMMANDS below) or marked to
       not receive SIGHUP using disown -h.

So, the question is, why won't the xmessage window linger without nohup?


Solution

disown is sufficient to prevent the shell from sending the signal, but it doesn't stop anyone else.

In particular, the shell is the controlling process of the terminal with xmessage in its process group, and POSIX says that on exit:

If the process is a controlling process, the SIGHUP signal shall be sent to each process in the foreground process group of the controlling terminal belonging to the calling process.



Answered By - that other guy