If I launch a background process and then log out, will it continue to run?
Asking this after a prolonged discussion with a coworker, I'd really like a clarification here.
I launch a background process, either by appending "&
" to the command line or by stopping it with CTRL-Z
and resuming it in background with "bg
". Then I log out.
What happens?
We were quite sure it should have been killed by a SIGHUP, but this didn't happen; upon logging in again, the process was happily running and pstree
showed it was "adopted" by init
.
Is this the expected behaviour?
But then, if it is, what's the nohup
command's purpose? It just looks like the process isn't going to be killed anyway, with or without it...
Edit 1
Some more details:
- The command was launched from a SSH session, not from the physical console.
- The command was launched without
nohup
and/or&
; it was then suspended withCTRL-Z
and resumed in background withbg
. - The ssh session did not drop. There was an actual logout ("
exit
" command). - The process was a
scp
file copy operation. - Upon logging in again,
pstree
showed the process running and being child ofinit
.
Edit 2
To state the question more clearly: will putting a process in background (using &
or bg
) make it ignore SIGHUP
, just like the nohup
command does?
Edit 3
I tried manually sending a SIGHUP
to scp
: it exited, so it definitely doesn't ignore the signal.
Then I tried again launching it, putting it in the background and logging off: it got "adopted" by init
and kept running, and I found it there when logging back on.
I'm quite puzzled now. Looks like no SIGHUP
was sent at all upong logging off.
Answer found.
For BASH, this depends on the huponexit
shell option, which can be viewed and/or set using the built-in shopt
command.
Looks like this options is off by default, at least on RedHat-based systems.
More info on the BASH man page:
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.
If the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an interactive login shell exits.
I agree with Warner and just want to add that you can keep the shell from sending SIGHUP with the builtin "disown" command. The bash man page contains a good description.
You can use the command nohup to launch the command and redirect output into a nohup output file. From the nohup man page:
nohup - run a command immune to hangups, with output to a non-tty
The other option is to use the screen command. The benefit of using screen is that you can reconnect to the process later.
When you fork a process into the background it will still be the child process from the shell executing it.
All child processes running under a shell are sent a SIGHUP upon exit. Performance varies slightly depending upon the exact situation, which is detailed verbosely in bash's manpage. Other shells likely have similar descriptions.
Apache, and other daemons, typically reload configuration on SIGHUP. Userspace utilities often die. Application performance linked to signals can be unique to the application.