Daemonizing Unix processes

From EggeWiki
Jump to navigation Jump to search

Have you ever attempted to log out from a Unix host, only to have your terminal session hang? This is often the result of an improperly started background process. Many of our scripts don't properly disconnect from a background process.

Let's say you want to write a script to run the following java process:

<geshi lang="bash"> java -cp $CP org.main.tomcat </geshi>

You should write it as:

<geshi lang="bash"> nohup java -cp $CP org.main.tomcat > console.log 2>&1 < /dev/null & </geshi>

nohup - this prevents the hang-up signal from being sent to your process. By default, processes which you launch in the background receive this signal when you attempt to logout, and your shell will wait for them to exit. This is similar to when you attempt to log off from windows.

To see this in action, try logging into an Unix host, and execute the following command in bash:

<geshi lang="bash"> (sleep 60; echo done sleeping) & logout </geshi>

You should now notice your session is hung. Wait a minute and the following will be displayed:

<geshi lang="bash"> done sleeping Connection to everest closed. </geshi>

Try the same thing with nohup:

<geshi lang="bash"> nohup /bin/bash -c "sleep 60; echo done sleeping" & [1] 19511 nohup: ignoring input and appending output to `nohup.out' </geshi>

Now, you can log out, log back in, and a minute later, you will see "done sleeping" in nohup.out. nohup will send both stderr and stdout to nohup.out by default. If you specify a location for stdout but not stderr, nohup will redirect stderr and alert you.

<geshi lang="bash"> nohup /bin/bash -c "sleep 5; echo some error 1>&2" > test.out & nohup: ignoring input and redirecting stderr to stdout </geshi>

While nohup will do the IO redirection for you, it's best to redirect the output yourself. This way it doesn't display a warning message, and you know the name of the file which will contain the output. Additionally, one should redirect all three streams. stdin should generally be redirected to /dev/null. Here's a recap

<geshi lang="bash"> nohup java -cp $CP org.main.tomcat > stdout.log 2>&1 < /dev/null &

nohup - ignore the hang-up signal > stdout.log - stdout redirect 2>&1 - stderr redirect < /dev/null - stdin redirect & - run in the background </geshi>


Q: We have log4j, so we can redirect the output to /dev/null.

A: All application level errors will show up in the log4j log, however, serious errors such as those coming from the C runtime, are only visible in the stderr log. Additionally, without the stderr, you can't easily get a stack trace using 'kill -3'. If the JVM crashes due to something like a stale NFS handle, the stderr log may be your only clue as to the reason for the crash.