Preventing Processes From Being Killed: An Overview Of Nohup And Disown

The Problem: Processes Getting Killed on Logout

When a user logs out of a Linux/UNIX system, the shell and associated processes are disrupted. Any foreground processes the user started are sent the HUP (hangup) signal by the shell. This signal causes processes to terminate by default. Background processes not disowned also receive HUP and may be killed depending on session settings.

This causes problems if you have long-running processes that need to continue executing after you log out or close the terminal. Processes like large file transfers, calculations, database queries, simulations, etc. would have to start over from scratch next login.

Fortunately, Linux/UNIX provides mechanisms for processes to ignore HUP signals and continue running after the user logs out. The nohup command and disown built-in make this easy.

nohup – Letting Processes Ignore Hangs Up

Overview & Examples of nohup

The nohup utility executes commands immune to hangups. It blocks SIGHUP signals being sent to the process and its children. The nohup command redirects stdout/stderr to a file nohup.out so the command’s output is not lost when the terminal closes.

For example, to have a Python script continue running in background after logout:

$ nohup python script.py &

The process ID is printed when it’s started. Tail nohup.out to view the program’s output:

$ tail -f nohup.out

This runs script.py, redirects output to nohup.out, and disables SIGHUP being sent on terminal exit. The process will continue executing even after logging out.

nohup Usage

The syntax of the nohup command is simple:

nohup COMMAND [ARGS] [OPTIONS]

Where COMMAND is the process or command being run. ARGS and OPTIONS are any required arguments or options for the COMMAND.

Common use cases for nohup include:

  • Running scripts/programs in the background – nohup python script.py &
  • Running daemon processes – nohup /usr/local/bin/daemon
  • Running queued/batched jobs – nohup nice bash job.sh
  • Offloading long tasks – nohup curl http://file.iso > file.iso

By default nohup sends output to nohup.out in the current directory. You can redirect stdout/stderr explicitly like:

nohup python script.py > my_output.log 2>&1

Be aware that nohup does not automatically put processes in the background. Append & like normal to have it run in background.

Caveats of nohup

While handy, nohup has some drawbacks to consider:

  • nohup backgrounds only the process it directly runs, not children
  • Output still associated with terminal unless redirected
  • Doesn’t disassociate process from shell/session

The last point means processes could still receive SIGHUP if the session ends as nohup protects only from terminal hangups. Using nohup in conjunction with disown is recommended for full protection after logout.

disown – Removing Processes From the Shell’s Job List

How Jobs & Job Control Work

Job control refers to the shell’s management of foreground/background processes. A job is a process the shell starts and keeps track of. The shell maintains a job list monitoring all jobs to handle suspending, resuming, termination signals, etc.

Shells track jobs associated with a session and send them SIGHUP on logout/disconnect by default. This kills long-running background jobs you want to keep alive after exiting.

Disowning Jobs from the Shell

The disown builtin removes jobs from the shell’s job list so they keep running independent of the session. Disowned jobs are immune to hangups as they dissociate from the controlling terminal.

To disown a running job, use:

disown %JOB_NUMBER

For example, to disown job 2:

  
$ disown %2

You can also disown the current foreground job using:

disown -h

Disowned jobs continue running but cannot be managed via the shell. Ensure long-running disowned processes redirect output so their status can still be monitored if needed.

Caveats of disown

Points to consider when using disown:

  • Disowned jobs no longer managed by the shell
  • Signals like ctrl-c no longer affect disowned processes
  • No way to get disowned jobs back under shell control

Also be aware disowning session leader processes will cause the whole session/shell to exit.

Best Practices for Keeping Processes Running

Based on the above, the recommended method for keeping jobs running even after logout or disconnection is:

  1. Start the long-running process
  2. Use nohup so it ignores hangups
  3. Disown the process to remove it from job control
  4. Optionally redirect output to a file

Example for a Python script:

$ nohup python script.py > my_output.log 2>&1 &
$ disown %1  

The script will now run in the background, ignoring SIGHUP signals, writing output to my_output.log. It will continue executing indefinitely, even if you logout or disconnect.

Check nohup.out or your redirected output file occasionally to monitor the disowned nohup process. Use ps to find and kill the PID when finished.

Following this reliable disown/nohup approach lets you spawn long-running batch jobs that continue processing in the background after you exit the shell.

Leave a Reply

Your email address will not be published. Required fields are marked *