10

After logging in through ssh, I type this command in bash:

sleep 50000000000000 &

Then I kill -9 the sleep process’s parent process (i.e., bash). Then the terminal window disconnects simultaneously.

When I log in again, I find that the sleep process is still alive.

Question: Why can the sleep process survive when I log out and the terminal is closed? In my mind, everything except daemons and nohup programs will be killed during logout. If sleep can survive in this way, does it mean that I can use this method instead of the nohup command?

  • 3
    & will fork the process to background (like daemon) and keeps running eventhough you are logged out. – Aizuddin Zali Oct 14 '15 at 6:28
6

Tl;dr:

Why can the sleep process survive when I log out and the terminal is closed? In my mind, everything except daemons and nohup programs will be killed during logout. If sleep can survive in this way, does it mean that I can use this method instead of the nohup command?

Unless the bash instance spawned by ssh has the huponexit option set, no process will be terminated by any mean upon exit / log out, and when the huponexit option is set, using kill -9 on the shell is not a good alternative to using nohup on the shell's child processes; nohup on the shell's child processes will still protect them from SIGHUPs not coming from the shell, and even when that is not important nohup is still to be preferred because it allows the shell to be terminated gracefully.


In bash there's an option called huponexit, which if set will make bash SIGHUP its children upon exit / logout;

In interactive non-login bash instances, such as in a bash instance spawned by gnome-terminal, this option is ignored; whether huponexit is set or unset, bash's children will never be SIGHUPped by bash upon exit;

In interactive login bash instances, such as in a bash instance spawned by ssh, this option is not ignored (however it is unset by default); if huponexit is set, bash's children will be SIGHUPped by bash upon exit / logout; if huponexit is unset, bash's children will not be SIGHUPped by bash upon exit / logout;

So in general exiting / logging out from an interactive login bash instance, unless the huponexit option is set, won't make the shell SIGHUP its children, and exiting / logging out from an interactive non-login bash instance won't make the shell SIGHUP its children regardless;

This is, however, irrelevant in this case: using kill -9 sleep will survive regardless, because killing its parent process (bash) won't leave a chance for the latter to do anything to the former (i.e., e.g., if the current bash instance was a login bash instance and the huponexit option was set, to SIGHUP it).

Adding to this, unlike other signals (like a SIGHUP signal sent to bash), a SIGKILL signal is never propagated to a process's child processes, hence sleep is not even killed;

nohup starts a process immune to SIGHUP signals, which is something different; it will prevent the process hanging up upon the reception of a SIGHUP signal, which in this case could be received by the interactive login bash instance in case the huponexit option was set and the shell exited; so technically using nohup to start a process in an interactive login bash instance with the huponexit option unset will prevent the process from hanging up upon the reception of a SIGHUP signal, but exiting / logging out of the shell won't SIGHUP it regardless;

In general, however, when nohup is needed to prevent SIGHUP signals coming from the parent shell, there's no reason to prefer the kill -9 on the parent method to the nohup on the child method; instead, it should be the opposite.

Killing the parent using the kill -9 method doesn't leave a chance for the parent to exit gracefully, while starting the child using the nohup method allows the parent to be terminated by other signals, such as SIGHUP (to make an example which makes sense in the context of a child started using nohup), which allow it to exit gracefully.

  • In other words, if I have a script that was placed in background,it will still be running even if I kill the parent process, e.g. my shell right ? what would be a way to kill that script ? – Sergiy Kolodyazhnyy Oct 14 '15 at 7:22
  • @Serg If you have the PID, simply killing the PID; if you didn't store the PID but you can identify the process by his name, ps -e | grep process should list the proces along with the PID (or better just pgrep -x process if you are sure to match that single process and not unwnated things); the problem is that when you kill a process with kill -9 its children get owned by upstart, hence their original PPID is lost and their PPID changes to upstart's PID, making them unrecognizable (AFAIK) but for their name or PID – kos Oct 14 '15 at 7:37
  • @kos Under what condition nohup will fail to prevent a process from hanging up upon receiving a SIGHUP signal from the parent process? I am trying to run a process in the background (in a PuTTY SSH shell terminal) by nohup <command> <arg> &. When I logout by clicking the PuTTY X button, the background process will terminate immediately. When I logout by typing exit in the PuTTY SSH shell terminal, the process will continue to run in the background. – userpal Apr 23 '16 at 5:25
3

bash by default does not send down the HUP signal to child processes when exiting. More in detail (thanks @kos), it never does it for non-login shells.

You can configure bash to do it for login shells if set the option huponexit. In a terminal, do:

[romano:~] % bash -l

(this start a new "login" shell)

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

Now check for the sleep process:

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

...not running: it has received the HUP signal and exited as requested.

  • @kos --- yes, you are right but ... so why if I sleep 1000 & ; exit the sleep survives? Notice that if I kill -HUP the sleep process it will exit. And even if huponexit set, the sleep survives. Confused... (I will try to understand better and modify the asnwer, otherwise I'll delete it). – Rmano Oct 14 '15 at 11:03
2

If sleep can survive in this way, if it means that I can use this method instead of nohup command?

kill -9 is really not the way one should go. It's like shooting with a gun at the TV to turn it off. Besides the comedic component there is no advantage. Processes can't catch or ignore SIGKILL. If you don't give the process a chance to finish what it's doing and clean up, it may leave corrupted files (or other state) around and won't be able to start again. kill -9 is the last hope, when nothing else works.


Why sleep process can survive when I logout and terminal is closed. In my mind, everything except daemon and nohup program will be killed when logout.

What in your case happens:

The parent process of sleep is the currently running bash shell. When you kill -9 that bash, the bash process has not the chance to send a SIGHUP to any of its child processes, because SIGKILL (which is sent by kill -9) is not catchable by the process. The sleep process continues running. sleep now became an orphan process.

The init (PID 1) process does a mechanism called reparenting. That means that the init process now becomes the parent of that orphaned process. init is an exception, processes can become it's child as it collects processes that lost their original parent process. Btw: A daemon (like sshd) does that when "going in the background".

If that whould not happen, the orphaned process would later (when finished) become a zombie process. This is what happens when waitpid() is not called (a responsibility of the parent process which cannot be fullfilled when when that process got killed). init calls waitpid() in an specific intervall to avoid zombie childs.

  • The process is surviving even with polite signals like TERM or HUP – heemayl Oct 14 '15 at 8:06
  • @heemayl HUP depends on the shells config: huponext. And TERM will wait until sleep finished. In case of the OPs sleep command, it would be thousands of years =) – chaos Oct 14 '15 at 8:29
1

The & starts the process in background. If you type ps -ef, you will see that parent process ID (PPID) of your sleep is your bash. Then logout and login again. The process will remain running after you logout. After you login for the second time you run ps -ef again. You will see that now the parent of your sleep process will be process with id "1". That is init, the parent of all processes.

0

Using & will cause program to run as background. To see the program in the background use bg command , and to make it running as foreground again, run fg.

Yes, there are many ways to keep program running even the main terminal exited.

  • thanks. the man page of bash is a little confusing. It said that : "Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. " BUT in fact, the shell only send SIGHUP to the forground jobs. the background processes have no chance to receive the SIGHUP signal (unless change the 'huponexit' shell options) – tom_cat Oct 14 '15 at 7:08
  • @kos maybe you are right. I draw the above conclusion from this post: stackoverflow.com/questions/4298741/… now, I get myself more confused. – tom_cat Oct 14 '15 at 7:55
  • @tom_cat Back to this again, thinking about it twice: there's simply no case in which the shell can exit with a foreground process running, it can be SIGHUPped or something, but that's not exiting. So that's correct, it applies only to background processes, because the opposite would make no sense. However from further research, mind also that huponexit works only on login shells such as a shell obtained via ssh (and not, say, in a shell obtained via gnome-terminal) – kos Oct 14 '15 at 10:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.