Why jobs aren’t killed at logout when executed with “> /dev/null 2>&1 &”

job-controlstdout

When you run jobs like the example below, they're killed when you logout:

$ ./job.sh &

However, when you execute them as in the below example, redirecting stdout to /dev/null and stderr to stdout as well as putting the job in the background, they're not killed when you log out. It's somewhat like nohup, except that the output goes to /dev/null instead of a file.

$ ./job.sh > /dev/null 2>&1 &

I noticed that some daemons work like that and then I got curious to know the reason why they aren't killed at logout.

Can someone explain me why?

EDIT 1:

As suggested by @Patrick on his comment, I tried the same with the simplest job ever and the result is the same: the job does not die when I log out.

# while true; do sleep 1; done > /dev/null 2>&1 &
[1] 4320
# logout

luis-macbook:~ luis$
luis-macbook:Downloads luis$ ssh server
luis.alen@server's password: 
# jobs
#
# ps -ef | grep 4320
root      4320     1  0 01:17 ?        00:00:00 -bash

EDIT 2:

As requested by Patrick again, I did the same test without redirecting the streams and, to my surprise, the process didn't die. Now I'm completely confused… I swear I remember processes put in background dying when you logged out. Am I absolutely wrong?

# while true; do sleep 1; done &
[1] 20720
# logout
luis-macbook:~ luis$ ssh server
# jobs
#
# ps -ef | grep 20720
root     20720     1  0 23:31 ?        00:00:00 -bash

Best Answer

As for daemons doing it, that's because they want any output or error messages they might produce to be discarded no matter how you redirect a process's input and output streams, it will still be SIGHUP'd if it's attached to a session and that session is closed to leave processes running.

To leave processes running, there are few approaches:

  1. detach them from the session — daemons do this by forking a new process and then exiting the original process; now the new process has no parent and is adopted by init you can also accomplish that using the bash internal command disown

  2. use nohup to block the process from receiving the SIGHUP when the session dies; the process doesn't get SIGHUP, doesn't exit, its parent dies and init adopts it

  3. attach it to a session that won't die — use screen

Please recheck your work on statement "Jobs aren't killed at logout when executed with > /dev/null 2>&1 &"

Related Question