Linux nohup Command: Keep a Command Running After Logout

nohup is a tool that runs a command while ignoring the SIGHUP signal, which may be sent when the terminal connection is lost. To continue a task after logging out, it is common to use nohup together with the background execution symbol &, and it is also recommended to explicitly specify the standard input and output files.

The most practical basic form is as follows.

nohup ./worker.sh > worker.log 2>&1 < /dev/null &

However, nohup is not a service manager that monitors or restarts processes. For long-term services that require automatic start after reboot, restart on failure, or log rotation, service management tools like systemd are more suitable.

What does the nohup command do?

nohup executes the specified command after setting it to ignore the hangup signal, SIGHUP. When closing a terminal or ending an SSH connection, SIGHUP may be sent to the shell and related processes, and ignoring it increases the likelihood that the task will continue running.

As can be seen in the official GNU Coreutils explanation of nohup, nohup itself does not send a command to the background. To continue other work in the current terminal, you need to separately add & at the end of the command.

Components What it does What it does not do
nohup Makes the command to be executed ignore SIGHUP. Does not automatically run in the background.
& Makes the shell execute the command as a background job. Does not guarantee ignoring SIGHUP.
Output Redirection Sends standard output and errors to the specified log file. Does not impose log size limits or automatic deletion.

Basic Syntax and Recommended Execution Form

Basic Syntax

After nohup, write the command and arguments to be executed in order.

nohup command [arg ...]

For example, to run backup.sh in the current directory, enter as follows.

nohup ./backup.sh

This form ignores SIGHUP but runs in the foreground. Therefore, it is difficult to enter the next command in the same shell until the command finishes.

Background Execution and Log Storage

In actual work, it is easier to manage if you specify background execution and the log path together.

nohup ./backup.sh > backup.log 2>&1 < /dev/null &
  • > backup.log writes the standard output to a new log file. If the same file exists, it overwrites the existing content.
  • 2>&1 sends the standard error to the same place as the current standard output.
  • < /dev/null replaces the standard input with a closed input source so that the program does not wait for terminal input.
  • The last & executes the command in the background.

To append new content to an existing log, use >> instead of >.

nohup ./backup.sh >> backup.log 2>&1 < /dev/null &

Save the PID immediately after execution

Right after executing a background command, $! contains the process ID (PID) of the most recently started background job. It is convenient to record this value in a safe place for later checking the status or terminating the process.

nohup ./backup.sh > backup.log 2>&1 < /dev/null &
job_pid=$!
printf '%s\n' "$job_pid" > backup.pid

Place the PID file in a directory that only the user managing the job can write to. If old PID files remain, the same number may be used by another process later, so it is safe to check the command and start time along with termination.

How are standard input and output handled?

Standard Input

In the GNU implementation, if standard input is connected to a terminal, nohup replaces it with an unreadable input source. This behavior reduces situations where the program stops waiting for input after the terminal disappears. To reduce implementation differences and clarify intent, you can explicitly write < /dev/null in the command.

Standard output and nohup.out

If standard output is directed to the terminal and no separate redirection is specified, GNU nohup appends the output to nohup.out in the current directory. If a file cannot be created in the current directory, it tries nohup.out in the user's home directory, and if both locations are not writable, the command will not execute.

If multiple tasks share the same nohup.out, it can be difficult to distinguish which task the logs belong to, and the file may continue to grow. It is better to specify a log file with a name and retention policy for each task.

Standard Error

If standard error is directed to the terminal, GNU nohup generally sends it to the same destination as standard output. However, depending on the shell, operating system, or redirections previously applied, readers may misunderstand the results, so it is safer to explicitly indicate your intention using 2>&1. The order of input/output connections in the shell affects the result, and the detailed principles can be found in the GNU Coreutils I/O Redirection documentation.

Checking Execution Status and Logs

Checking Processes with Saved PID

If you have the PID saved right after execution, you can pass it directly to ps to check its status.

job_pid=$(cat backup.pid)
ps -p "$job_pid" -o pid,ppid,stat,etime,cmd

PID is the process ID, PPID is the parent process ID, STAT is the status, and ELAPSED is the execution time. Do not assume it is the desired task just because the PID exists; also check the command column at the end.

Finding a process by name

If the PID was not saved, you can search the command line with pgrep.

pgrep -af 'backup.sh'

Since other processes containing the same string may also be found, you should check the entire command line of the result. Simply piping the ps output into grep often shows the search command itself and is therefore not suitable for automation.

Checking logs in real time

Using tail -f allows you to continuously view additions to the end of a file.

tail -f backup.log

To stop monitoring the log, press Ctrl+C. This only terminates tail and does not stop the original task writing the log. You can see more details about specifying the number of lines and tracking files in how to use the tail command.

Terminating a process started with nohup

First, request a normal termination

After checking the target PID and command, running kill basically sends the SIGTERM signal. If the program has termination handling code, it gets a chance to close files and clean up its state.

job_pid=$(cat backup.pid)
ps -p "$job_pid" -o pid,ppid,stat,etime,cmd
kill "$job_pid"

Checking whether it has terminated

Wait a moment and then check the same PID again.

ps -p "$job_pid" -o pid,stat,etime,cmd

If a shell script has created multiple child processes, terminating just one parent may leave the children running. Check the process tree and process groups first, and if the program you are using provides an official termination command, prioritize using that.

Use force termination as a last resort

If you immediately force terminate just because it does not respond to SIGTERM, data may not be saved, or temporary files may not be cleaned up. Make sure the cause and target are correct, and use SIGKILL only as a last resort.

kill -KILL "$job_pid"

Running pipelines and compound commands

Grouping into a single shell command

You can pass a command string to the shell to execute a pipeline, multiple redirections, and conditional operators as a single task.

nohup sh -c 'producer | consumer' > pipeline.log 2>&1 < /dev/null &

At this time, the pipeline inside the quotes is interpreted by a new shell. If you merge external input into the command string without validation, there is a risk of command injection, so do not insert untrusted values directly. You can also refer to How to Use Bash Command Connection Operators for the execution relationship of shell operators.

When logs are not immediately visible

If the process is running but the logs appear late, the cause could be the program's output buffering rather than nohup. First, check the log flushing settings of the program itself. In GNU-based environments, if the program and output method are compatible, you can request line buffering with stdbuf.

nohup stdbuf -oL -eL ./worker > worker.log 2>&1 < /dev/null &

stdbuf does not work for all programs. If the program resets its own buffer or uses a specific input/output method, it may not apply.

Limits of nohup and criteria for choosing other tools

Features not provided by nohup

nohup is a simple execution tool that changes the handling of one signal. The following features are not provided.

  • Automatic start after system reboot
  • Automatic restart when the process terminates abnormally
  • Managing the startup order of dependent services
  • Resource limitation and status monitoring such as CPU and memory
  • Log file size limitation, compression, retention, and deletion
  • Preservation of interactive terminal sessions

Differences with systemd, tmux, screen

Tools Suitable situations Features
nohup Temporarily running non-interactive batch tasks Simple, but does not have monitoring, restart, or log rotation functions.
systemd Services that run continuously on the server You can configure boot integration, restart policies, dependencies, and manage logs and resources.
tmux/screen Interactive tasks that need to be reconnected later You can detach and reconnect virtual terminal sessions.
Task scheduler Tasks to be executed at a fixed time or interval Manage execution timing and history using cron or a dedicated job queue.

Difference from disown

disown is a shell built-in feature in some shells like Bash that removes a job already started from the shell's job list or changes its hangup signal handling method. In contrast, nohup is an external program that causes a command to ignore SIGHUP from the moment it starts. Since disown's options and behavior vary depending on the shell, you should check the current shell's documentation for portable scripts.

Checklist for safe execution

  • Path: Specify scripts, configuration files, and log files by absolute path whenever possible. This ensures the same files are used even if the login location changes.
  • Permissions: Check whether passwords, tokens, or personal information could remain in logs, and restrict file permissions.
  • Size: Configure logrotate or the program's own log retention policy to prevent logs from continuously growing.
  • Duplicate execution: Check if it is safe for the same task to run multiple times simultaneously. If necessary, use lock files or the program's single execution feature.
  • Environment: In non-interactive execution, the working directory, PATH, locale, and environment variables may differ from the login shell, so specify the necessary values.
  • Sensitive arguments: If you pass passwords or tokens as command-line arguments, other users can see them in the process list. Use credential files or secret storage methods supported by the program.
  • Termination procedure: Record the PID immediately after execution and prepare both the normal termination method and steps to check any remaining child processes.

Frequently Asked Questions

Will a nohup job definitely persist if I close the SSH window?

Commands started with nohup ignore SIGHUP, but this does not absolutely guarantee job persistence in all environments. If a program creates separate child processes while changing signal settings or continues using the terminal device, the outcome may differ. Detach both standard input and output from the terminal, and for important long-running tasks, it is safer to use a service manager.

How can I prevent creating the nohup.out file?

You can directly specify standard output and standard error. Only tasks that do not require any logging at all can be sent to /dev/null, but as diagnostic information will also be lost, it is usually recommended to use separate log files for operational tasks.

nohup ./worker > /dev/null 2>&1 < /dev/null &

Why don't jobs appear in jobs?

jobs only shows tasks managed by the current shell. If you log out and connect with a new shell, the previous shell's job list does not carry over, so it won't appear in jobs. Use the saved PID and ps, or use the status-checking function of service management tools.

What does nohup's exit code mean?

In the GNU implementation, separate exit codes are used for errors in nohup itself, cases where the command cannot be found, or cases where the command cannot be executed. If the command starts successfully, it returns the exit status of that command. The exact value can be affected by the implementation and the POSIXLY_CORRECT setting, so for automation, check nohup --help and the official documentation of the system. Note also that after starting in the background and exiting the shell, you cannot simply read $? in that shell to get the final task result.

Summary

nohup executes a command so that it ignores SIGHUP, which can occur when logging out or closing the terminal. Typical non-interactive tasks use nohup together with & and explicit standard input/output redirection, and saving the PID immediately after execution makes management easier.

If the task needs to start even after a reboot or requires automatic recovery in case of failure, choose a service manager like systemd instead of nohup. To take a look at other basic tools at a glance, you can refer to the List of frequently used commands in Linux.

More in This Category
Linux type Command: Identify How a Command Is Resolved

Linux type Command: Identify How a Command Is Resolved

Learn how to use the Linux type command to identify aliases, functions, built-ins, keywords, and executable paths, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux dmesg Command: Read Kernel and Boot Messages

Linux dmesg Command: Read Kernel and Boot Messages

Learn how to read Kernel and Boot Messages with the Linux dmesg command, including practical examples, key options, and important precautions.

Linux uname Command: Check Kernel and System Architecture

Linux uname Command: Check Kernel and System Architecture

Learn how to check Kernel and System Architecture with the Linux uname command, including practical examples, key options, and important precautions.

Linux which Command: Find Executables in PATH

Linux which Command: Find Executables in PATH

Learn how Linux which searches PATH for executables, shows all matching paths, differs from type and command -v, and should be used carefully in scripts.

Linux tree Command: Display a Directory Tree

Linux tree Command: Display a Directory Tree

Learn how to use the Linux tree command to display directory contents as a readable hierarchy and control depth and filtering, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux tracepath Command: Trace a Network Path and Path MTU

Linux tracepath Command: Trace a Network Path and Path MTU

Learn how to trace a Network Path and Path MTU with the Linux tracepath command, including practical examples, key options, and important precautions.

Linux cut Command: Extract Characters and Fields

Linux cut Command: Extract Characters and Fields

Learn how to extract Characters and Fields with the Linux cut command, including practical examples, key options, and important precautions.

Linux umask Command: Control Default File Permissions

Linux umask Command: Control Default File Permissions

Learn how to control Default File Permissions with the Linux umask command, including practical examples, key options, and important precautions.

Linux lsblk Command: Inspect Disks, Partitions, and Mounts

Linux lsblk Command: Inspect Disks, Partitions, and Mounts

Learn how to inspect Disks, Partitions, and Mounts with the Linux lsblk command, including practical examples, key options, and important precautions.

Linux who Command: List Logged-In Users

Linux who Command: List Logged-In Users

Learn how to list Logged-In Users with the Linux who command, including practical examples, key options, and important precautions.