Bash – Does backgrounded child process die with parent

background-processbashprocess

I have a script which calls several other sub-scripts. It is later killed and this seems to kill all the sub-scripts.

For the most part this is what I want. But there is a case or two where I don't want a child to die.

I think I remember being able to stop this from happening by backgrounding with a & when calling a script.

Can anyone confirm this?

Best Answer

There are a lot of factors to consider here. Please take this answer with a slight grain of salt as I'm writing all these details from memory. (And please correct me via edits or comments if you spot any mistakes.)

If you background a command with & and then the parent shell exits normally, the background command will keep running.

However, if you're running interactively, the "backgrounded" command will get blocked when it tries to read from or write to the terminal. (This applies whether or not the parent shell is still running.) If stdout, stdin and stderr are redirected this won't matter.

If you background a command and then e.g. your SSH session is disconnected, you can expect the backgrounded command to terminate. I believe this is because your shell will send SIGHUP to all its child processes, but I'm not 100% certain on the details of that.

If you disown a job (with the bash builtin disown) after you background it, then it won't be terminated just because e.g. your SSH session is terminated. However, the aspect of getting blocked when trying to write to terminal or read from terminal still applies (for interactive sessions).

The most general way I know of to start a sub-script or process in the background such that it will not be affected no matter what happens to the shell which spawns it (and regardless of whether it's being started interactively or from a script), is:

nohup somecommand >/dev/null 2>&1 </dev/null &

This assumes you don't care about ANY output of the command to its standard out or standard error, and don't need to feed it any standard input.

If you're happy for the sub-script to inherit the file descriptors of its parent (i.e. terminal is not a problem or you have some other solution), then really all you need should be:

./some-sub-script &
exit

And just a side comment, if you're writing a daemon which is intended to be left running, please (a) use logs and (b) take care of rotating your logs cleanly.

Related Question