Home / Alt manpages / nohup(1)

  • nohup(1)
  • User command
  • linux

Keep a Command Running After You Disconnect with nohup

nohup keeps a command running after its terminal closes, ignoring the hangup signal that would otherwise kill it. Close the terminal on an ordinary foreground command and it usually dies with it. You will finish with a command still running, its output written somewhere you chose, and a way to check on it without guessing. The examples use GNU coreutils nohup 9.4, installed here as coreutils 9.4-3ubuntu6.3.

Allow about ten minutes. You need a shell and a command that can run without an interactive terminal. No elevated privileges are needed for the examples. This guide starts a background process; it does not install anything, edit a service, or change persistent configuration.

1. Confirm which nohup you are using

Run these read-only checks first:

$ command -v nohup
/usr/bin/nohup
$ nohup --version
nohup (GNU coreutils) 9.4
$ dpkg-query -W -f='${Package} ${Version}\n' coreutils
coreutils 9.4-3ubuntu6.3

The installed command here is GNU nohup, but your shell may provide its own builtin or function of the same name, and that takes precedence when it exists, changing available options and details of behaviour. If command -v points at something other than /usr/bin/nohup, read that shell's own documentation before relying on GNU-specific details.

Checkpoint

Make sure the command you test is the command you intend to use. nohup --help is a safe way to inspect the local option list too.

2. Run a harmless command in the background

nohup ignores hangup signals for the command it starts, but it does not background the command by itself: add & when you want your shell prompt back:

$ nohup sh -c 'printf "%s\n" "job started"; sleep 30' &
[1] 24831
nohup: ignoring input and appending output to 'nohup.out'
$
  • The job number and PID vary each run; treat them as illustrative.
  • The nohup.out message appears because standard output is still a terminal and no output file was given.
  • Standard input gets redirected from an unreadable file when it is a terminal, so the command cannot accidentally wait for input from the session you just disconnected.

That command is only a smoke test. Replace the quoted shell command with your real one, keeping its arguments after nohup, and quote anything with spaces or shell metacharacters. If the command needs a password, a menu selection, terminal dimensions, or any interactive session, nohup is the wrong tool entirely.

3. Choose the output file explicitly

For a repeatable job, pick a path instead of relying on the default file, and redirect both output and error so diagnostics do not get mixed in by accident:

$ mkdir -p "$HOME/nohup-runs"
$ nohup sh -c 'printf "%s\n" "job started"; sleep 5; printf "%s\n" "job finished"' \
    > "$HOME/nohup-runs/example.log" \
    2>&1 &
[1] 24902
$

Warning

The shell only opens the log in append mode when nohup itself chooses nohup.out. The explicit > above truncates an existing file before the command even starts, destroying the old log. Use >> instead when earlier runs matter:

$ nohup sh -c 'printf "%s\n" "another run"' \
    >> "$HOME/nohup-runs/example.log" \
    2>&1 &

There is no undo for a truncated log; recover it from a backup or archive if one exists. The directory itself is reversible with rmdir once its files are gone, but never remove a directory holding unrelated data.

4. Verify the process and its log

Capture the process ID straight away if you need to check on the child later:

$ nohup sh -c 'sleep 20; printf "%s\n" "finished"' \
    > "$HOME/nohup-runs/check.log" 2>&1 &
$ pid=$!
$ printf 'started pid: %s\n' "$pid"
started pid: 24920
$ kill -0 "$pid" 2>/dev/null && printf '%s\n' 'process is still present'
process is still present
$ wait "$pid"
$ cat "$HOME/nohup-runs/check.log"
finished

The PID here is only an example. kill -0 does not terminate anything: it just asks the kernel whether a process with that ID can be signalled. A successful check proves the process still exists, not that it is healthy. wait is useful when you launched the job from the current shell, since it hands back the child's exit status.

To watch a growing log without changing it, use tail -f in another terminal. Stop that viewer with Ctrl-C; it does not touch the nohup job itself.

5. Interpret failures and exit statuses

GNU nohup returns the command's exit status when it successfully starts the command. Its own failures use 125. A command that was found but could not be invoked returns 126, and one that could not be found returns 127:

$ nohup definitely-not-a-command > /tmp/nohup-test.log 2>&1
$ printf 'status: %s\n' "$?"
status: 127
$ cat /tmp/nohup-test.log
nohup: failed to run command 'definitely-not-a-command': No such file or directory

Do not hide these statuses with an unconditional true or by closing standard error. Check the log and the status from the shell that started the command. For anything long-lived, add application-level health checks too: nohup only handles terminal hangups and output redirection, not crashes, restarts, resource limits or supervision.

6. Stop a job you no longer need

A nohup process is not immortal. If you saved its PID, ask it to stop normally:

$ kill "$pid"
$ wait "$pid" 2>/dev/null || printf '%s\n' 'job stopped'

Only reach for kill -KILL after a normal termination request has failed, and only once you understand the risk: the process cannot clean up or save state when the kernel forcibly ends it. For recurring or production work, use a real service manager such as systemd rather than building a fragile supervisor around nohup.

Done means

  • Confirmed the binary: you checked whether your shell selected GNU coreutils nohup.
  • Backgrounded correctly: you added & when you needed the shell prompt back.
  • Log path chosen deliberately: an explicit path, with truncation versus append understood.
  • Process checked: you recorded a PID and verified the process or its exit status.
  • No false confidence: you know nohup does not replace supervision for services or interactive commands.