# nohup — Detach Processes from the Terminal

> nohup detaches commands from the terminal so they ignore SIGHUP and keep running after logout – ideal for backups and long-running jobs over SSH.

Source: https://www.jpkc.com/db/en/cheatsheets/shell-system/nohup/

<!-- PROSE:intro -->
Start a long-running command over SSH, lose the connection, and the process is usually gone – closing the terminal sends SIGHUP and takes it down with you. `nohup` shields exactly that signal: the command ignores SIGHUP and keeps running, even after you log out. Combined with `&` to background it and a redirection for its output, it becomes the classic way to detach a job from the terminal.
<!-- PROSE:intro:end -->

## Basic Usage

`nohup <command>` — Run a command immune to hangups. Output is appended to ./nohup.out (or $HOME/nohup.out if cwd is not writable).

```bash
nohup ./long-running-task.sh
```

`nohup <command> &` — Run in the background AND immune to SIGHUP — survives terminal close. The typical invocation.

```bash
nohup ./backup.sh &
```

`nohup <command> arg1 arg2 &` — Pass arguments to the command as usual.

```bash
nohup rsync -av /data/ user@host:/backup/ &
```

`nohup --version` — Show GNU coreutils version (BusyBox/macOS nohup do not support --version).

```bash
nohup --version
```

## Output Redirection

`nohup <command> > out.log 2>&1 &` — Redirect both stdout and stderr to a custom log file instead of nohup.out.

```bash
nohup ./worker.sh > worker.log 2>&1 &
```

`nohup <command> > out.log 2> err.log &` — Separate stdout and stderr into different files.

```bash
nohup ./build.sh > build.log 2> build.err &
```

`nohup <command> >> out.log 2>&1 &` — Append to an existing log file (useful when restarting a job).

```bash
nohup ./service.sh >> /var/log/service.log 2>&1 &
```

`nohup <command> > /dev/null 2>&1 &` — Discard all output entirely. Common for fire-and-forget tasks.

```bash
nohup ./cleanup.sh > /dev/null 2>&1 &
```

`nohup <command> < /dev/null > out.log 2>&1 &` — Also redirect stdin from /dev/null — fully detaches from the terminal (no SIGTTIN if the term is closed).

```bash
nohup ./server.sh < /dev/null > server.log 2>&1 &
```

## Capturing the PID

`nohup <command> > out.log 2>&1 & echo $!` — Print the PID of the backgrounded job. $! is the PID of the most recent background process.

```bash
nohup ./worker.sh > worker.log 2>&1 & echo $!
```

`nohup <command> > out.log 2>&1 & echo $! > task.pid` — Save the PID to a file for later management (kill, status checks).

```bash
nohup ./worker.sh > worker.log 2>&1 & echo $! > worker.pid
```

`kill $(cat task.pid)` — Stop a previously started nohup job using the saved PID.

```bash
kill $(cat worker.pid)
```

## Running Pipelines & Shell Scripts

`nohup bash -c '<cmd1> | <cmd2>' &` — nohup only protects the FIRST command. Wrap pipelines or redirections in 'bash -c' so the whole pipeline is shielded.

```bash
nohup bash -c 'tail -f app.log | grep ERROR > errors.log' &
```

`nohup bash -c '<cmd1>; <cmd2>; <cmd3>' &` — Run a sequence of commands in one nohup'd shell.

```bash
nohup bash -c './backup.sh; ./upload.sh; ./cleanup.sh' &
```

`nohup ./script.sh &` — Run a script that already contains pipelines/loops. Inside the script, only the script itself needs nohup.

```bash
nohup ./deploy.sh > deploy.log 2>&1 &
```

## Combining with Other Tools

`nohup <command> & disown` — Belt-and-braces: nohup ignores SIGHUP, disown removes the job from the shell's table. Survives even if 'shopt -s huponexit' is set.

```bash
nohup ./server.sh > server.log 2>&1 & disown
```

`setsid nohup <command> &` — Start in a new session AND immune to SIGHUP — fully detached from the terminal session.

```bash
setsid nohup ./daemon.sh > daemon.log 2>&1 &
```

`nice -n <prio> nohup <command> &` — Run a long-living background job at a lower CPU priority.

```bash
nice -n 19 nohup ./compress-archives.sh &
```

`ionice -c 3 nohup <command> &` — Run with idle I/O priority (only uses disk when nothing else needs it).

```bash
ionice -c 3 nohup ./backup.sh &
```

`ssh user@host 'nohup <command> > out.log 2>&1 &'` — Start a remote background job via SSH that survives the SSH session closing.

```bash
ssh deploy@web01 'nohup ./restart.sh > restart.log 2>&1 &'
```

## Checking & Stopping

`ps -ef | grep <command>` — Verify the nohup'd process is still running.

```bash
ps -ef | grep worker.sh
```

`tail -f nohup.out` — Watch the default output log live.

```bash
tail -f nohup.out
```

`tail -f <custom.log>` — Watch a custom log file live.

```bash
tail -f worker.log
```

`kill <pid>` — Send SIGTERM to a nohup'd process by PID.

```bash
kill 4242
```

`kill -9 <pid>` — Force-kill (SIGKILL) a process that won't terminate gracefully.

```bash
kill -9 4242
```

`pkill -f <pattern>` — Kill by command-line pattern when you didn't save the PID.

```bash
pkill -f worker.sh
```

## nohup vs. Alternatives

`<command> & disown` — disown alone removes the job from the shell's table. Without nohup, SIGHUP is still delivered if 'huponexit' is on.

```bash
long-task & disown
```

`setsid <command>` — Starts the command in a new session — no controlling terminal, so SIGHUP cannot reach it.

```bash
setsid ./daemon.sh
```

`tmux new -d -s <name> '<command>'` — Run inside a detached tmux session — keeps a TTY for later interactive attachment.

```bash
tmux new -d -s build 'make all'
```

`screen -dmS <name> <command>` — Equivalent for GNU Screen — start in a detached named session.

```bash
screen -dmS build make all
```

`systemd-run --user --unit=<name> <command>` — Run as a transient systemd user unit — get logging via journalctl and lifecycle control via systemctl.

```bash
systemd-run --user --unit=build make all
```

## Common Recipes

`nohup <command> > out.log 2>&1 < /dev/null & echo $!` — Robust template: detached from stdin, all output to one file, PID printed for later management.

```bash
nohup ./worker.sh > worker.log 2>&1 < /dev/null & echo $!
```

`Promote a running foreground job` — Already-running command in the foreground? Suspend, background, then disown — note: nohup cannot be applied retroactively.

```bash
Ctrl+Z
bg
disown -h %1
```

`ssh -n -f host 'nohup <cmd> > /tmp/out 2>&1 &'` — Fire-and-forget remote start: -n redirects stdin from /dev/null, -f backgrounds ssh after authentication.

```bash
ssh -n -f deploy@web01 'nohup ./deploy.sh > /tmp/deploy.log 2>&1 &'
```

`Cron without log spam` — In cron, nohup is unnecessary (cron has no controlling terminal). Use plain redirection — keep it simple.

```bash
*/5 * * * * /usr/local/bin/job.sh > /var/log/job.log 2>&1
```

<!-- PROSE:outro -->
## Conclusion

`nohup` is the quickest way to cut a command loose from the terminal: prefix it with `nohup`, add `&` to background it, done – the job survives logout and a dropped SSH session. For more robustness, redirect output explicitly (`> log 2>&1`) instead of relying on `nohup.out`, detach stdin from `/dev/null`, and capture the PID with `echo $!`. Know one limit, though: nohup offers no reattach – if you want to drop back into the running session later, `screen` or `tmux` are the better fit, and for genuine, long-lived services the process belongs in a `systemd` unit rather than behind nohup.

## Further Reading

- [GNU Coreutils: nohup invocation](https://www.gnu.org/software/coreutils/manual/html_node/nohup-invocation.html) – official reference for the GNU implementation of nohup
- [man7.org: nohup(1)](https://man7.org/linux/man-pages/man1/nohup.1.html) – the Linux manual page for nohup
<!-- PROSE:outro:end -->

## Related Commands

- [jobs](https://www.jpkc.com/db/en/cheatsheets/shell-system/jobs/) – list background and suspended jobs of the current shell
- [screen](https://www.jpkc.com/db/en/cheatsheets/shell-system/screen/) – terminal multiplexer with detachable, reattachable sessions
- [tmux](https://www.jpkc.com/db/en/cheatsheets/shell-system/tmux/) – modern terminal multiplexer with reattach and pane splits

