How to Background a Running Process Without Stopping It in Linux (bg/fg vs & Explained)


3 views

When you press Ctrl+Z in a terminal, you're sending a SIGTSTP (terminal stop) signal, which pauses the process and moves it to the background. This is problematic when you actually want the process to keep running while freeing up your terminal.


# This will STOP the process (undesired behavior)
$ python long_running_script.py
^Z
[1]+  Stopped                 python long_running_script.py

Here are three correct approaches to background processes without interruption:

Method 1: Start with Ampersand (&)


# The process starts immediately in background
$ python long_script.py &
[1] 12345  # PID shown

Method 2: Job Control with bg

If you already started a process and want to background it:


# Start process
$ python import_data.py
^Z  # Pause first
[1]+  Stopped                 python import_data.py

# Then resume in background
$ bg %1
[1]+ python import_data.py &

Method 3: Using nohup for Persistent Tasks


$ nohup python server.py > output.log 2>&1 &
[1] 67890
$ disown -h %1  # Optional: remove from shell's job table

For production environments, consider these professional tools:


# Using screen (multiple terminal sessions)
$ screen -S data_processing
$ python processor.py
^A^D  # Detach (Ctrl+A then D)

# Later reattach
$ screen -r data_processing
Command Purpose
jobs List background jobs
fg %n Bring job n to foreground
kill %n Terminate background job
disown Remove from job table

Many developers mistakenly believe Ctrl+Z is the proper way to background a process. While it does move the process to the background, it simultaneously suspends execution. This behavior stems from its original purpose as a signal handler (SIGTSTP) rather than a backgrounding tool.

To run a process in the background without stopping it, you have two primary methods:

# Method 1: Append & during command launch
long_running_process --param value &

# Method 2: For already running foreground process
# Press Ctrl+Z to suspend, then:
bg %1  # Resume in background

For processes already suspended (via Ctrl+Z), you can resume them with these commands:

jobs               # List all jobs
fg %1              # Resume in foreground
bg %2              # Resume in background
disown -h %3       # Detach from terminal

For production environments, consider these robust approaches:

# Use nohup to prevent SIGHUP on terminal exit
nohup ./server.sh > output.log 2>&1 &

# Alternative using tmux/screen for session persistence
tmux new-session -d -s mysession './worker.sh'

# Systemd service for critical processes
[Unit]
Description=My Background Service

[Service]
ExecStart=/usr/local/bin/service
Restart=always
User=worker

[Install]
WantedBy=multi-user.target

When background processes behave unexpectedly:

  • Check for terminal output conflicts (redirect to /dev/null or files)
  • Verify process isn't waiting for terminal input (use EOF or input redirection)
  • Ensure proper signal handling (trapping SIGTERM/SIGINT in scripts)

Here's a complete workflow for data processing:

# Start processor in background
data_processor -i input.csv -o output.json &

# Check status
jobs -l

# If suspended (shows "Stopped"):
bg %1

# To make persistent after terminal closes:
disown %1