19

I read an answer from a user who claimed that running

foo 2>&1 >& output.log &

would result in foo continuing to run even when they log out. According to this user, this even worked over SSH connections.

I didn't really believe that, as I was under the impression that in the case of disconnecting from SSH, or terminating the TTY, the shell and therefore its processes would receive a SIGHUP, causing them to terminate. This, under my assumption, was the sole reason for using nohup in such cases, or tmux, screen et al.

I then looked into glibc's manual:

This signal is also used to report the termination of the controlling process on a terminal to jobs associated with that session; this termination effectively disconnects all processes in the session from the controlling terminal.

This seems to confirm my thoughts. But looking further, it says:

If the process is a session leader that has a controlling terminal, then a SIGHUP signal is sent to each process in the foreground job, and the controlling terminal is disassociated from that session.

So, does this mean jobs put in background will not receive SIGHUP?

To my further confusion, I ran an interactive Zsh session, ran yes >& /dev/null &, and typed exit, when Zsh warned me that I had running jobs, and after typing exit for a second time, told me that it had SIGHUPed one job. Doing exactly the same in Bash leaves the job running…

slhck
  • 463
  • 1
  • 6
  • 22
  • I've had problems with a server in the past that gets suddenly disconnected over ssh, and my process just kept running but without any tty associated, so I had to login again and send SIGHUP/TERM/KILL to end them. So, following the same logic, I have tested just now, typed `logout` and `yes` is still running. – Braiam Jul 28 '13 at 21:08
  • In addition to whether or not SIGHUP is sent, whether a process has defined a signal handler (and catches SIGHUP) or signal mask are additional factors in whether it is terminated when sent that signal. So just because it remains running after logout doesn't mean it wasn't sent that signal – Tim B Aug 02 '13 at 13:05
  • Are you referring to this question: http://serverfault.com/questions/115999/if-i-launch-a-background-process-and-then-log-out-will-it-continue-to-run ? The answer seems to be found there - it's RedHat not setting shopt by default. It's RedHat's particular configuration quirk. – Boris Burkov Aug 02 '13 at 15:07
  • @Bob No, I haven't seen this one before, but it's a good resource. Thanks! – slhck Aug 02 '13 at 15:21
  • Glad it helped. Actually Raphael is referring to that issue too. – Boris Burkov Aug 02 '13 at 15:28

1 Answers1

28

Bash seems to send the SIGHUP only if it self received a SIGHUP, which for example occurs when a virtual terminal is closed or when the SSH connection is interrupted. From the documentation:

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 SIGHUP signal to a particular job, it should be removed from the jobs table with the disown builtin (see Job Control Builtins) or marked to not receive SIGHUP using disown -h.

So if you type exit or press Ctrl+D all background process will remain, since this does not send a hang up signal to the Bash.

You can force Bash to warn you about the fact that there are still running background processes with

shopt -s checkjobs

There is an option to send the SIGHUP on exit if you are in an interactive shell(see here). But it doesn't work on my machine with Bash 4.2.25. Maybe it works for you

shopt -s huponexit
Raphael Ahrens
  • 9,701
  • 5
  • 37
  • 52
  • 3
    So, when an SSH connection interrupts, `SIGHUP` is sent, otherwise, with a clean exit, jobs continue running? That explains what I saw. – slhck Aug 02 '13 at 14:54
  • Yes. The hang up signal is only there for the special case, when the connection with the user is interrupted. – Raphael Ahrens Aug 03 '13 at 07:55
  • Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/30342/discussion-between-martin-kunev-and-raphael-ahrens). – Martin Kunev Oct 16 '15 at 11:09
  • 2
    [`huponexit` is "only in effect for interactive login shells"](http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00091.html) – npostavs Nov 08 '15 at 16:30
  • @npostavs thanks for the information I added it into the answer. – Raphael Ahrens Nov 09 '15 at 07:34
  • I think it's worth emphasizing the "a virtual terminal is closed" part. If you close the window, `SIGHUP` is sent, if you do Ctrl-D/`exit`, it isn't. On a [side note](https://unix.stackexchange.com/a/6337/29867). – x-yuri Nov 16 '21 at 01:58