How to Run Linux Commands in the Background

By 

Updated on

9 min read

Running commands in the background in Linux

When you run a command in the terminal, the shell waits for it to finish before accepting the next command. This is called a foreground process. When a process runs in the foreground, it occupies your shell and you cannot run other commands until it completes.

A background process runs concurrently with the shell, freeing the terminal for other work while the command continues. This guide explains how to start commands in the background, move foreground jobs to the background, and keep processes running after the shell session ends.

Quick Reference

TaskCommand
Run command in backgroundcommand &
Group commands into one job(command1; command2) &
Get PID of last background jobecho $!
Suppress all outputcommand > /dev/null 2>&1 &
List background jobsjobs -l
Check whether a PID existsps -p PID
Bring job to foregroundfg %1
Resume suspended job in backgroundbg %1
Suspend foreground processCtrl+Z
Disown a jobdisown %1
Protect a job but keep it listeddisown -h %1
Run with nohupnohup command &
Detach with setsidsetsid command > output.log 2>&1 < /dev/null &
Wait for all background jobswait
Terminate by PIDkill PID

Run a Command in the Background

To run a command in the background, add the ampersand symbol (&) at the end of the command:

Terminal
command &

The shell prints the job ID (in brackets) and the process ID (PID):

output
[1] 25177

You can have multiple processes running in the background at the same time. To get the PID of the most recently backgrounded process, use the $! variable:

Terminal
command &
echo "PID: $!"

By default, the background process continues to write output to the terminal. To suppress both stdout and stderr, redirect them to /dev/null:

Terminal
command > /dev/null 2>&1 &

> /dev/null discards standard output, and 2>&1 redirects stderr to stdout, so both streams are silenced.

The & operator backgrounds the command construct that comes before it. In command1 & command2, the shell backgrounds command1 and immediately runs command2 in the foreground. To send a semicolon-separated sequence to the background as one job, group it in parentheses:

Terminal
(command1; command2) &

The parentheses start a subshell, so the commands still run one after another, but the shell treats the group as a single background job. A shell script works the same way, since one & covers everything the script does:

Terminal
./backup.sh > backup.log 2>&1 &

Manage Background Jobs

Use the jobs utility to list all stopped and background jobs in the current shell session:

Terminal
jobs -l
output
[1]+ 25177 Running                 ping google.com &

The output shows the job number, PID, state, and the command that started the job. The jobs command reports only jobs owned by the current shell, so a process you started in another terminal will never show up here.

To check whether a particular PID currently exists, pass it to ps :

Terminal
ps -p 25177
output
    PID TTY          TIME CMD
  25177 pts/0    00:00:00 ping

If no process has that PID, ps prints the header and nothing else. Inside a script, kill -0 performs the existence and permission checks without sending a signal:

sh
if kill -0 "$pid" 2>/dev/null; then
  echo "process exists"
fi

Neither check proves that the original process is actively running. A zombie still has a PID until its parent reaps it, and the system can reuse a PID after a process exits.

To bring a background process to the foreground, use the fg command:

Terminal
fg

If you have multiple background jobs, specify the job ID with %:

Terminal
fg %1

To terminate a background process, use the kill command with the PID. Send SIGTERM first to allow the process to exit cleanly:

Terminal
kill 25177

If the process does not respond, force-terminate it with SIGKILL:

Terminal
kill -9 25177

Move a Foreground Process to the Background

To move a running foreground process to the background:

  1. Press Ctrl+Z to suspend the process. The shell prints the job number and a Stopped status.
  2. Run bg to resume the process in the background:
Terminal
bg

If you have multiple suspended jobs, specify which one to resume:

Terminal
bg %1

Run Multiple Commands in Parallel

Backgrounding several commands at once lets them run in parallel instead of one after another. Append & to each command, then use the wait built-in to block until all of them finish:

Terminal
command1 &
command2 &
wait
echo "Both commands finished"

The wait built-in pauses the script until every background job in the current shell completes. To wait for one specific job, pass its PID:

Terminal
command1 &
pid=$!
wait "$pid"

This pattern is common in scripts that start independent tasks together and then continue once all of them are done.

Keep Background Processes Running After the Shell Exits

Closing the terminal window usually terminates a background job that uses the default SIGHUP handling. The terminal sends a SIGHUP (hangup) signal to the shell, and Bash forwards that signal to every job it owns, running or stopped.

Logging out by typing exit behaves differently. For an interactive login shell, Bash sends SIGHUP to its jobs on exit only when the huponexit option is enabled, and that option is off by default:

Terminal
shopt huponexit
output
huponexit      	off

With the default setting, a running job started with & generally survives a clean exit. When the terminal window closes, Bash receives SIGHUP and forwards it, and programs using the default signal action terminate. Programs can catch or ignore SIGHUP, so protect long-running jobs explicitly with disown, nohup, or setsid.

disown

disown removes a job from the shell’s job table, so the shell no longer forwards SIGHUP to it:

Terminal
disown

To disown a specific job by ID:

Terminal
disown %1

Confirm the job was removed with jobs -l . Because the job no longer appears in the job table, fg and bg can no longer reach it either. When you want to keep managing the job from the shell and still shield it from SIGHUP, use -h, which marks the job instead of removing it:

Terminal
disown -h %1

Two more options help when several jobs are involved. The -a option applies to every job, and -r narrows the action to jobs that are still running:

Terminal
disown -a

Note that disown does not redirect the process output. If the terminal closes, any output the process tries to write will produce an error.

nohup

The nohup command runs a program and ignores all SIGHUP signals. It also redirects output to nohup.out automatically:

Terminal
nohup command &
output
nohup: ignoring input and appending output to 'nohup.out'

If you log out or close the terminal, the process continues running. To redirect output to a specific file instead:

Terminal
nohup command > output.log 2>&1 &

setsid

setsid runs a command in a new session that initially has no controlling terminal, so a hangup from the original terminal does not reach it through that terminal relationship. It does not make the command ignore a SIGHUP sent directly by another process. Redirect input and output, then background the command so your shell prompt returns immediately:

Terminal
setsid command > output.log 2>&1 < /dev/null &

Unlike nohup, setsid does not redirect output automatically. If you leave output connected to the terminal, the process can still try to write there after you close the session.

Alternatives: Screen and Tmux

Terminal multiplexers create persistent sessions that survive disconnections. Unlike disown or nohup, they let you reconnect to a running session and interact with processes.

Screen

Screen (GNU Screen) lets you open multiple windows inside a single session. Start a named session:

Terminal
screen -S backup

Run whatever you need inside it, then press Ctrl+a followed by d to detach. The session and everything in it stay alive after you disconnect. To reattach from any terminal, including a fresh SSH connection:

Terminal
screen -r backup

To launch a command in a detached session without ever attaching to it, combine -d and -m:

Terminal
screen -dmS backup ./backup.sh

Tmux

Tmux is a modern alternative to Screen and follows the same pattern. Create a named session:

Terminal
tmux new -s backup

Detach with Ctrl+b followed by d, then reattach whenever you need to check on it:

Terminal
tmux attach -t backup

Tmux can also start a session detached in a single step:

Terminal
tmux new -d -s backup ./backup.sh

Troubleshooting

bg: no current job
There is no suspended job in the current shell session. Press Ctrl+Z to suspend a running foreground process, then run bg, or specify an existing job ID such as bg %1.

There are stopped jobs when closing the terminal
The shell is warning that suspended jobs still exist. Run jobs -l to inspect them, then use fg to resume and stop them cleanly, or run bg and disown if you need them to continue.

nohup: failed to open 'nohup.out'
The current directory is not writable. GNU nohup tries $HOME/nohup.out next. To choose the destination yourself, redirect to a path you can write, such as nohup command > "$HOME/output.log" 2>&1 &.

Process stops when the terminal is closed even though it was backgrounded with &
& alone does not protect against SIGHUP. Closing the terminal signals Bash, which forwards the signal to its jobs. A program using the default signal action then terminates. Start the command with nohup command &, run disown -h %1 against a job that is already going, or use Screen or Tmux when you need a persistent interactive session.

FAQ

What is the difference between disown and nohup?
nohup is set before the process starts, makes it ignore SIGHUP, and redirects terminal output to nohup.out. disown is applied after the process is already running and prevents Bash from forwarding SIGHUP to that job. Unlike nohup, disown does not change the process signal handling or redirect its input and output.

How do I see all background processes, not just jobs in the current shell?
Use ps aux to list all running processes, or filter by name with ps aux | grep command.

Can I run multiple commands in the background at the same time?
Yes. Append & to each command. Use jobs -l to see all running background jobs and their job IDs.

What happens to background job output if I close the terminal?
If you used & alone, Bash normally forwards SIGHUP when the terminal closes, and a process using the default signal action terminates. If you used nohup, output is saved to nohup.out. If you used disown, the process continues but may error when trying to write to the closed terminal.

How do I run a command in the background and log its output?
Redirect output to a file: command > output.log 2>&1 &. To also keep it running after logout, combine with nohup: nohup command > output.log 2>&1 &.

Conclusion

To run a command in the background, append & to it. Use disown to detach a running job from the shell, or nohup to start a process that survives logout with output saved automatically. For interactive sessions that survive disconnections, use Screen or Tmux .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page