opscape

Processes and jobs · bash builtin

bg

Resume a stopped job in the background, as if it had been started with &.

bg [JOBSPEC...]

5 of 5 examples run in Debian 13.7 on 2026-10-31 · manual: bash(1)

You started something long in the foreground (tar czf backup.tgz ~/projects, a build, a big copy) and want your prompt back without killing it. Press Ctrl-Z to stop it, then type bg: the job continues running in the background, exactly as if you had added & to the command, and the shell prints [1]+ tar czf backup.tgz ~/projects &. That is all bg does: it sends CONT to a stopped job and leaves it in the background.

Without an argument bg resumes the current job (marked + in jobs); with job specs (bg %2 %3) it resumes several. A backgrounded job keeps writing to your terminal, and if it tries to read from the terminal it is stopped again (Stopped (tty input)), so bg suits jobs that do not need input.

Like fg, bg needs job control. Interactive shells have it; scripts, and the bash -c these examples run in, have to enable it with set -m. Ctrl-Z needs a real terminal, so the examples stop jobs with kill -TSTP, which sends the same signal.

Examples

bg in a script without job control

sleep 300 &
bg
outputexit 1
/bin/bash: line 2: bg: no job control

no job control, exit status 1: a non-interactive shell cannot stop and resume jobs. Scripts start background work with & directly and never need bg.

Resume a stopped job in the background

set -m
sleep 300 &
kill -TSTP %1
sleep 0.1
jobs
bg
jobs
output
[1]+  Stopped                 sleep 300
[1]+ sleep 300 &
[1]+  Running                 sleep 300 &

kill -TSTP %1 stops the job as Ctrl-Z would (Stopped). bg prints the job with a trailing & and resumes it; jobs now shows it Running.

Resume several stopped jobs at once

set -m
sleep 300 &
sleep 600 &
kill -TSTP %1 %2
sleep 0.1
jobs
bg %1 %2
jobs
output
[1]-  Stopped                 sleep 300
[2]+  Stopped                 sleep 600
[1]- sleep 300 &
[2]+ sleep 600 &
[1]-  Running                 sleep 300 &
[2]+  Running                 sleep 600 &

bg accepts several job specs and resumes each in turn. With no argument only the current (+) job would be resumed.

bg on a job that is already running

set -m
sleep 300 &
bg %1
echo "exit status: $?"
output
/bin/bash: line 3: bg: job 1 already in background
exit status: 0

bash notes job 1 already in background and does nothing; this is not an error, so the exit status is 0.

Background a job and let it survive logout

set -m
sleep 300 &
kill -TSTP %1
sleep 0.1
bg %1
disown %1
jobs
pgrep -a sleep
output
[1]+ sleep 300 &
162 sleep 300

The rescue sequence for a long job you started in the foreground: Ctrl-Z, bg, then disown, which removes it from the job table so the shell will not send it HUP when you log out. jobs is now empty, but pgrep shows the process still running.

Common pitfalls

  • Backgrounding a job that reads from the terminal. It stops again immediately with Stopped (tty input); bring it back with fg, or restart it with input from a file or /dev/null.

  • Backgrounded jobs still print to the terminal and still die with it. For anything long, prefer nohup cmd > log 2>&1 & from the start, or bg followed by disown.

  • Ctrl-Z, then forgetting the job is stopped rather than running. jobs shows Stopped; only bg (or fg) makes it continue.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • bg is a POSIX builtin in every job-control shell (bash, zsh, ksh, dash) on Linux and macOS. disown is not POSIX: bash and zsh have it, dash does not.

Related