Keep a Linux Command Running After You Disconnect with nohup
You will finish with a command that keeps running after its terminal closes, writes output somewhere you choose, and can be checked without guessing whether it survived. The examples use GNU coreutils nohup 9.4, installed here as coreutils 9.4-3ubuntu6.3.
The route
Jump straight to the step you need, or tick off Done means at the end.
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 but 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 is GNU nohup. Your shell may provide a builtin or function with the same name, and the shell's implementation takes precedence when it does. That can change the available options or details of the behaviour. If command -v identifies something other than /usr/bin/nohup, read that shell's documentation before relying on GNU-specific details.
Checkpoint
Make sure the command you test is the command you intend to use. nohup --help is also a safe way to inspect the local option list.
2. Run a harmless command in the background
nohup ignores hangup signals for the command it starts. It does not put the command in the background by itself, so 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 process ID vary. The message about nohup.out appears because standard output is still a terminal and no output file was supplied. Standard input is redirected from an unreadable file when it is a terminal, so a command cannot accidentally wait for input from the disconnected session.
The command above is only a smoke test. Replace the quoted shell command with your real command, keeping its arguments after nohup. Quote values that contain spaces or shell metacharacters. If the command needs a password, menu selection, terminal dimensions or an interactive session, nohup is the wrong tool.
3. Choose the output file explicitly
For repeatable jobs, choose a path instead of relying on the default file. Use both output and error redirections so diagnostics are not mixed accidentally:
$ 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
$
The shell opens the log in append mode only when nohup itself chooses nohup.out. The explicit > above truncates an existing file before starting the command. That is destructive to the old log. Use >> instead when retaining earlier runs matters:
$ 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 your normal backup or log archive if one exists. The directory creation is reversible with rmdir after its files have been removed, but do not remove a directory that contains unrelated data.
4. Verify the process and its log
Capture the process ID immediately if you need to check the child:
$ 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 is an example. kill -0 does not terminate the process: it asks the kernel whether a process with that ID can be signalled. A successful check does not prove that the command is healthy, only that the process still exists and is visible to you. wait is useful when you launched the job from the current shell because it returns the child's status.
To watch a growing log without modifying it, use tail -f in another terminal. Stop that viewer with Ctrl-C; it does not stop the nohup job.
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 a command 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. If the command is long-lived, also arrange application-level health checks: 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 use kill -KILL after a normal termination request has failed and 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 service manager such as systemd rather than building a fragile supervisor around nohup.
Done means
- You confirmed whether your shell selected GNU coreutils nohup.
- You used
&when you needed the shell prompt back. - You selected an explicit log path and understood whether
>truncates it. - You recorded a PID and checked the process or its exit status.
- You know nohup does not replace supervision for services or interactive commands.