Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Use nohup to keep a process running

By updated

Improve this page

nohup command & is all you need to type for a command to survive your SSH disconnection. When the terminal closes, your shell receives the SIGHUP signal and relays it to its jobs, which end. nohup makes the command ignore that signal, and sends its output away from the vanished terminal. The behaviours described here were measured on Debian 13, Ubuntu 24.04 and AlmaLinux 10, by actually closing the terminal of an interactive Bash.

What you will learn

  • Understand why a process dies on disconnection (SIGHUP)
  • Run a command with nohup and &
  • Redirect stdout and stderr to a dedicated log file
  • Combine nohup with disown for maximum protection
  • Find the process again after reconnecting with pgrep or ps

In which context?

nohup answers a precise need: start a long job on a remote machine and cut the connection without killing it. The three situations below share the same point, a process that lasts longer than your session. If, on the contrary, you need to see the output live again after reconnecting, or take control of the program again, nohup is not enough and tmux is what you need, compared at the end of this guide.

  • You start a backup, a compilation, a data transfer over SSH.
  • You cannot or do not want to leave the terminal open.
  • tmux is not available on the remote machine.

Why processes die on disconnection

When you disconnect from an SSH session, the terminal disappears and the kernel sends SIGHUP (signal 1, hang up) to the shell, which relays it to its jobs before quitting. By default, most commands react to SIGHUP by ending. Measured by closing the terminal of an interactive Bash, identically on the three distributions:

LaunchAfter the terminal closes
sleep 600 &dead
sleep 600 > log 2>&1 &dead: redirecting the output does not protect
nohup sleep 600 > log 2>&1 &alive
sleep 600 & then disownalive
nohup sleep 600 in the foreground, without &alive, but the terminal was blocked

To reproduce the effect without disconnecting, send the signal yourself to the process whose PID you noted:

Terminal window
kill -HUP "$PID"

nohup works around this mechanism by setting SIGHUP to be ignored before running the command. One exception to know: if the administrator set KillUserProcesses=yes in /etc/systemd/logind.conf, systemd kills every process of the session on disconnection, nohup included. The three distributions ship the default value no (line #KillUserProcesses=no, read in the file).

Basic syntax

The form to remember has two elements that play distinct and complementary roles: nohup detaches the command from the SIGHUP signal, and & sends it to the background to give you control back. The most common oversight is typing nohup command without the &: the command does ignore SIGHUP, but it takes over your terminal, and you can do nothing more in it until the end. Note the $! variable right after the launch, it holds the PID of the last process put in the background, your only reliable way to find it again later.

Terminal window
nohup command arguments &
  • nohup: sets SIGHUP to be ignored, then runs the command
  • &: puts the process in the background (essential, without &, nohup blocks the terminal)
Terminal window
# Concrete example
nohup rsync -avz /data/ user@server:/backup/ &
echo "Backup started, PID=$!"

The nohup.out file

If you do not redirect the output, nohup automatically creates a nohup.out file in the current directory to capture stdout, and says so (message read in the C locale):

Terminal window
cd ~
nohup my-script.sh &
# nohup: ignoring input and appending output to 'nohup.out'
ls -la nohup.out
tail -f nohup.out # follow the progress

If the current directory is not writable, nohup falls back to $HOME/nohup.out and announces it: measured, a user standing in a root-owned directory gets appending output to '/home/testeur/nohup.out'.

The good practice is to name the log file yourself, with an absolute path, so that you always know where to look:

Terminal window
nohup my-script.sh > /var/log/my-script.log 2>&1 &
PID=$!
echo "PID=$PID, logs in /var/log/my-script.log"
  • > file.log: redirects stdout
  • 2>&1: redirects stderr to the same file
  • When you redirect explicitly, nohup.out is not created

To follow the progress in real time from another connection:

Terminal window
tail -f /var/log/my-script.log

Combine nohup and disown

nohup protects against SIGHUP. disown removes the job from the shell's job table. Combined, they offer maximum protection:

Terminal window
nohup my-command > output.log 2>&1 &
PID=$!
disown $PID
echo "Job $PID started, protected against HUP and detached from the shell"

When to use the combination?

  • When you work in an interactive shell and want no risk of a premature end.
  • When you also want the job to disappear from jobs, so as not to confuse it with the next ones.

Find a nohup process after reconnecting

After disconnecting and reconnecting, your new shell has no memory of the previous jobs: jobs shows nothing. Find the process by its name with pgrep, which only compares the first 15 characters of the name; for a script with a long name, search the full command line with pgrep -f.

Terminal window
# By command name
pgrep -a my-script
pgrep -u bob rsync
# By PID (if you noted it)
ps -p 1234 -o pid,stat,comm,etime
# Read the logs
tail -f /var/log/my-script.log

Summary: nohup vs disown vs tmux

The four approaches differ on when you decide (before or after launch) and on what you can still see after reconnecting. The table sums up the trade-offs.

ToolWhen to use itAdvantageLimit
nohup command &Simple job, single connectionOne command is enoughNo interactivity afterwards
disown -h $PIDCommand already started without nohupRescue after the factThe output still points to the closed terminal if it was not redirected
nohup ... & disownMaximum protectionSIGHUP ignored and detachedNo interactive resume
tmuxInteractive session, live follow-upFull reconnection possibleRequires tmux installed

Troubleshooting

Almost every trouble with nohup revolves around two oversights: the missing &, which freezes the terminal, and the missing redirection, which scatters nohup.out files in the launch directory. The table below starts from the observed symptom, because it is what you see first; in each case, the real cause is almost always one of these two missed reflexes. Remember that nohup.out is written in the current directory at launch time, not where the script works afterwards.

SymptomLikely causeSolution
nohup.out missing while the job runsOutput redirected explicitlyNormal, look for your log file
nohup.out in the wrong foldernohup creates the file in $PWD at launch timeAlways give an absolute path in the redirection
The terminal stays blocked after nohup command& forgotten: the command runs in the foreground (it still survives the disconnection, measured)Ctrl+Z then bg, or restart with nohup command &
The job dies despite nohupKillUserProcesses=yes in /etc/systemd/logind.confCheck this setting, or run the job as a service
Cannot find the process after reconnectingPID not noted, command too genericAlways note the PID or use a command with a unique name
Two nohup.out getting mixedTwo nohup jobs in the same directory without redirectionUse separate log files for each job

Key points

  • nohup makes SIGHUP ignored: the command no longer ends on SSH disconnection, where a plain & dies (measured).
  • Without a redirection, the output goes to nohup.out, or to $HOME/nohup.out if the current directory is protected.
  • Always add &, without it nohup blocks your terminal.
  • Redirect explicitly to a log file: nohup command > my.log 2>&1 &
  • Combine with disown $! for full protection.
  • Note the PID or use an explicit log name to find the job again after reconnecting.

Knowledge check

Check that the essentials of this guide stuck. The questions cover only what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn