Bash Job Control: Manage Foreground and Background Jobs
Bash job control lets you pause, resume, and manage commands from one interactive terminal. Start a command in the background, move a running job between foreground and background, and check its status without opening another terminal.
What You’ll Need
- A Unix-like system with Bash, such as Linux or macOS.
- An interactive terminal running Bash. Job control is generally unavailable in non-interactive shell scripts.
- A command you can safely test, such as
sleep 60. Avoid experimenting with commands that modify files or services.
Step-by-Step
- Check that job control is active. In an interactive Bash prompt, run
set -o | grep monitor. If the output saysmonitor on, job control is enabled. It is normally on in an interactive shell. If it is off, enable it withset -m. This setting applies to the current shell. - Run a command in the foreground. Enter a command and press Enter, for example
sleep 60. Bash waits for it to finish, so you cannot enter another command at that prompt while it is running. The terminal is connected to the foreground process group, which can read terminal input and receive keyboard signals. - Start a new command in the background. Add an ampersand (
&) at the end:sleep 60 &. Bash returns a job number and a process ID, then displays the prompt again. The job number, shown in brackets such as[1], is a shell job identifier; the PID is an operating-system process identifier. Use the job number with job-control commands. - List the shell’s jobs. Run
jobsto see jobs started from this shell, including whether they are running, stopped, or done. For process details such as CPU use, use a process-monitoring command such asps;jobsis not a system-wide process list. Add-ltojobsto include process IDs. - Pause a foreground command. While a foreground command is running, press Ctrl+Z. This sends the terminal’s stop signal to the foreground job and returns you to the prompt. The command is suspended, not completed or terminated. Check its state with
jobs. - Resume a stopped job in the background. Run
bgto continue the most recently stopped job without bringing it to the foreground. To choose a specific job, use its job number:bg %1. The percent sign is required for a job specification. If the job is already running, Bash may report that there is no stopped job to resume. - Bring a job to the foreground. Run
fgfor the current or most recently used job, or specify one withfg %1. The command resumes if stopped, and your terminal waits on it again. Press Ctrl+C to interrupt a foreground job if you want to stop it; that is different from Ctrl+Z, which suspends it. - Stop a background job deliberately. Use
kill %1to send the default termination signal to job 1. This requests that the job exit; it may take a moment, and some programs handle the request before exiting. Confirm the result withjobs. Usekill -STOP %1to suspend a job explicitly, orkill -CONT %1to continue a suspended one. Prefer the job specification when targeting a job from the current shell. - Manage terminal output and input. Background jobs can still write to the terminal, so their output may interleave with your commands. To save output, redirect it when starting the command, for example
long_command >run.log 2>&1 &. A background command that tries to read from the terminal may be stopped by the shell. Provide input from a file, such ascommand <input.txt &, or run it in the foreground. - Finish or leave jobs intentionally. A completed job may remain in the job list until Bash reports or removes it. Run
wait %1to wait for a particular background job to finish and collect its exit status;waitwithout an argument waits for applicable jobs. When you exit a shell, its jobs do not automatically become durable background services. Bash may warn about stopped or running jobs; return to them, stop them, or deliberately arrange a separate session or service if they must outlive the terminal.
Common Mistakes
- Confusing job numbers and PIDs:
%1means job 1 in this shell;1234may be a PID. A job number can change between shells and is not a permanent process identifier. - Expecting Ctrl+Z to cancel: It suspends the foreground job. Use Ctrl+C or a suitable
killcommand to request termination. - Assuming
&makes a process independent: It runs asynchronously in the current shell’s job table, but it can still use the terminal and may be affected when the shell exits. - Using job-control commands in a script: Non-interactive shells usually do not provide the same job-control behavior. For scripts, use process IDs,
wait, and explicit signal handling as appropriate. - Forgetting output redirection: Background output can clutter the prompt. Redirect standard output and standard error when that is useful, and choose a log filename that will not overwrite important data.
Tips
- Use
jobs -lbefore acting if you are unsure which process a job number refers to. - Use
fgwhen a program needs interactive input, andbgfor stopped work that can continue without terminal interaction. - Try the workflow safely with
sleep 60: start it, suspend it, inspect it, resume it withbg, and bring it back withfg. - Job control is scoped to the shell that started the jobs. A new terminal or shell has a different job list.
Troubleshooting
fg or bg says there is no such job: Run jobs -l in the same shell that started the command. It may have finished, or you may be in a different shell. Use a listed job specification such as %2.
A background job stops as soon as it reads input: This is expected terminal behavior. Bring it forward with fg %n, or restart it with input redirected from a file or pipe.
Ctrl+Z does nothing: Confirm the command is running in the foreground of an interactive Bash terminal. The key may be intercepted by a terminal application or configured differently; inspect the terminal’s settings or use kill -STOP with the correct job or PID.
kill %n does not immediately remove a job: The signal requests termination, but the program may need time to exit. Check jobs again. If it remains, verify the target before sending another signal; avoid force-killing processes unless necessary, because they cannot clean up normally.
Output appears after the prompt or gets mixed with commands: Redirect output when starting the job, or bring it to the foreground. The prompt returning does not mean the background command has finished.
Frequently Asked Questions
What is the difference between a job and a process?
A process is an operating-system task with a PID. A job is Bash’s way of tracking a command or pipeline started by that shell; a job can contain multiple processes.
Can I run several commands in the background?
Yes. End each command with &, then use jobs to identify them. Each job receives a job number in that shell.
Does closing the terminal stop background jobs?
It may. Jobs are not guaranteed to survive shell exit or terminal closure. Use a session manager or service designed for persistent work when a task must continue independently.
How do I see a background command’s exit status?
Use wait %n for a job that has not yet been collected. Bash returns its exit status; capture it immediately with status=$? if you need to use it later.
Can I bring a job to the foreground from another terminal?
No. Bash job-control commands operate on jobs known to the current shell. Use a process-management or terminal-session tool appropriate to how the process was started.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.