This is a followup to this question.
I've run some more tests; looks like it really doesn't matter if this is done at the physical console or via SSH, neither does this happen only with SCP; I also tested it with cat /dev/zero > /dev/null. The behaviour is exactly the same:
- Start a process in the background using
&(or put it in background after it's started usingCTRL-Zandbg); this is done without usingnohup. - Log off.
- Log on again.
- The process is still there, running happily, and is now a direct child of
init.
I can confirm both SCP and CAT quits immediately if sent a SIGHUP; I tested this using kill -HUP.
So, it really looks like SIGHUP is not sent upon logoff, at least to background processes (can't test with a foreground one for obvious reasons).
This happened to me initially with the service console of VMware ESX 3.5 (which is based on RedHat), but I was able to replicate it exactly on CentOS 5.4.
The question is, again: shouldn't a SIGHUP be sent to processes, even if they're running in background, upon logging off? Why is this not happening?
Edit
I checked with strace, as per Kyle's answer.
As I was expecting, the process doesn't get any signal when logging off from the shell where it was launched. This happens both when using the server's console and via SSH.
-
It will be sent SIGHUP in my tests:
Shell1:
[kbrandt@kbrandt-opadmin: ~] ssh localhost [kbrandt@kbrandt-opadmin: ~] perl -e sleep & [1] 1121 [kbrandt@kbrandt-opadmin: ~] ps PID TTY TIME CMD 1034 pts/46 00:00:00 zsh 1121 pts/46 00:00:00 perl 1123 pts/46 00:00:00 psShell2:
strace -e trace=signal -p1121Shell1 Again:
[kbrandt@kbrandt-opadmin: ~] exit zsh: you have running jobs. [kbrandt@kbrandt-opadmin: ~] exit zsh: warning: 1 jobs SIGHUPed Connection to localhost closed.Shell2 Again:
strace -e trace=signal -p1121 Process 1121 attached - interrupt to quit pause() = ? ERESTARTNOHAND (To be restarted) --- SIGHUP (Hangup) @ 0 (0) --- Process 1121 detachedWhy does it still run?:
Advanced Programing in the Unix Environment by Stevens covers this under section 9.10. Orphaned Process Groups. The most relevant seciont being:Since the process group is orphaned when the parent terminates, POSIX.1 requires that every process in the newly orphaned process group that is stopped (as our child is) be sent the hang-up signal (SIGHUP) followed by the continue signal (SIGCONT).
This causes the child to be continued, after processing the hang-up signal. The default action for the hang-up signal is to terminate the process, so we have to provide a signal handler to catch the signal. We therefore expect the printf in the sig_hup function to appear before the printf in the pr_ids function.
Massimo : But you explicitly sent a SIGHUP to it here; I was talking about what happens when you log off from the shell where you started the process.Kyle Brandt : Same results when I type exit, although I get a warning about jobs, but then type exit again. I tested this with ZSH.Massimo : I'm using BASH, and this probably depends on the shell. But BASH *should* send SIGHUP to child processes when logging off...Kyle Brandt : Bash sends SIGCONT apparently if the job is stopped, but I confirm it doesn't send anything if the job was not stopped.From Kyle Brandt -
Answer found.
For BASH, this depends on the
huponexitshell option, which can be viewed and/or set using the built-inshoptcommand.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.
CarpeNoctem : Verified. When I performed an "exit", "logout", or CTL-D the child proc (job) would not receive a sighup (both root and reg user). However when I did "kill -HUP $$" to kill the current instance of bash the child processes DID receive a sighup. I then set huponexit and the child process did receive SIGHUP upon exit.Warner : Good stuff, man.From Massimo -
I use csh and background processes continue running along when I logoff.
From Chris S
0 comments:
Post a Comment