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:
disownremoves a specified job ID from the shell’s tracking table. When the shell terminates, it only sendsSIGHUPto jobs remaining in that table. - Post-Execution Intervention: Unlike
nohup, which must be invoked before launching a command (e.g.nohup ./script.sh &),disowncan 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 + Zandbg.
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
- Whilst the process is running in your foreground terminal, press
Ctrl + Zto send aSIGTSTPsignal. The process pauses, and the terminal displays a job number:[1]+ Stopped ./long_task.sh - Resume the process in the background by typing:
The shell confirms the process is running in the background:bg[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
jobswhile shielding it from closing signals, use the-hflag:
This instructs the shell not to senddisown -h %1SIGHUPto job%1upon exit, while keeping it manageable viafgas 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.