How to Use the disown Command in Linux to Detach Running Processes from Terminals

Starting a long-running compiling job, file download, or database backup in a Linux terminal without running it inside tmux or screen often presents a dilemma. When you need to close your terminal emulator or disconnect an active SSH session, any process launched from that shell will automatically receive a Hangup Signal (SIGHUP) from the kernel and terminate immediately. The built-in Bash and Zsh shell command disown solves this by stripping running background jobs from the shell’s active job table, allowing them to persist independently after logout.

Understanding How SIGHUP and disown Work

When an interactive terminal window closes, the shell broadcasts a SIGHUP (Signal Hangup) to all child processes registered in its internal job table. By default, processes that do not explicitly catch this signal crash immediately:

  • Job Table Removal: disown removes a specified job ID from the shell’s tracking table. When the shell terminates, it only sends SIGHUP to jobs remaining in that table.
  • Post-Execution Intervention: Unlike nohup, which must be invoked before launching a command (e.g. nohup ./script.sh &), disown can be applied retroactively to any command that is already running.
  • Background Requirement: Before a running command can be disowned, it must first be placed in the background state using Ctrl + Z and bg.

Step-by-Step: Disowning an Already Running Process

If you launched an intensive script and realise you need to shut down your workstation without interrupting it:

Step 1: Suspend and Background the Process

  1. Whilst the process is running in your foreground terminal, press Ctrl + Z to send a SIGTSTP signal. The process pauses, and the terminal displays a job number:
    [1]+  Stopped                 ./long_task.sh
  2. Resume the process in the background by typing:
    bg
    The shell confirms the process is running in the background:
    [1]+ ./long_task.sh &

Step 2: Inspect Active Jobs

Verify the job number assigned to your process by querying the shell’s jobs list:

jobs -l

This displays the job index (such as [1]) alongside the process ID (PID).

Step 3: Execute the disown Command

Disown the specific background job from the shell’s management:

disown %1

If you have only one background job running, running disown without arguments detaches the most recent job automatically.

Step 4: Close the Terminal Safely

Type exit or close the terminal window. The process will continue running seamlessly in the background, adopting PID 1 (systemd or init) as its parent process.

Useful disown Command Flags and Variations

The disown command provides several specialised flags for varied system administration workflows:

  • Disown All Jobs: To detach every background task currently running under your active shell session simultaneously:
    disown -a
  • Keep in Table but Ignore SIGHUP: If you want the job to remain visible in jobs while shielding it from closing signals, use the -h flag:
    disown -h %1
    This instructs the shell not to send SIGHUP to job %1 upon exit, while keeping it manageable via fg as long as the terminal stays open.
  • Disown Running Jobs Only: To detach only active executing jobs while ignoring paused/stopped tasks, combine flags:
    disown -ar

Preventing Stale Standard Output (stdout/stderr)

When disowning a task, remember that its standard output streams remain bound to the pseudo-terminal where it started. If the script attempts to write to standard output after the terminal closes, it can encounter a broken pipe error:

  • Redirecting on Launch: If possible, redirect outputs when starting background jobs:
    ./task.sh > task.log 2>&1 &
    disown
  • Verifying Persistence: After exiting your terminal, open a new shell and verify the process is still executing by checking pgrep -l -f task.sh.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.