Job Control Basics

GNU Screen & Linux Job Control

Chapter 5 ยท Shell Job Control Basics

Screen gives you many terminals. Job control lets one terminal run several things at once: starting commands in the background, pausing them, and moving them between the background and the foreground. It's built into the shell. This chapter uses bash, but zsh and most other modern shells behave the same way. It's also the foundation for Chapter 8, where you move an already-running job into screen.

Foreground and Background

A command normally runs in the foreground: it owns the terminal, receives what you type, and you get your prompt back only when it finishes. Add & to the end of a command and it runs in the background instead, and the prompt comes back straight away.

$ sleep 300 & [1] 48213 $ # prompt is back immediately

The shell prints two numbers: [1] is the job number, and 48213 is the process ID (PID). They are different things, and Chapter 6 is all about the difference. When the job finishes, the shell tells you the next time it shows a prompt:

[1]+ Done sleep 300

Pausing a Job: Ctrl-Z

If a command is already running in the foreground, Ctrl-Z suspends it. The shell sends the job the SIGTSTP signal: the job stops where it is — not ended, just frozen — and you get your prompt back.

$ tar czf backup.tar.gz /home/philip ^Z [1]+ Stopped tar czf backup.tar.gz /home/philip
Ctrl-Z is not Ctrl-C
Ctrl-C sends SIGINT, which normally ends the program. Ctrl-Z only pauses it. A stopped job does no work at all until you resume it — a paused backup isn't making progress in the background.

Listing Jobs

$ jobs [1]- Stopped tar czf backup.tar.gz /home/philip [2]+ Running sleep 300 &

Each line shows the job number, a marker, the state (Running, Stopped, Done), and the command. The + marks the current job, the one commands act on by default; the - marks the previous job. jobs -r lists only running jobs, and jobs -s only stopped ones.

Moving Jobs Around: fg and bg

CommandWhat it does
fgBring the current job to the foreground (resuming it if stopped)
fg %2Bring job 2 to the foreground
bgResume the current stopped job in the background
bg %1Resume job 1 in the background
kill %1Send job 1 the SIGTERM signal, asking it to end
waitWait until all background jobs have finished
The most useful pattern
You start a long command, then realise you want your prompt back. Press Ctrl-Z, then type bg. The job carries on in the background, and you can keep working. This is also the first step in Chapter 8's rescue technique.

Referring to Jobs: Job Specs

SpecRefers to
%1Job number 1
%% or %+The current job (marked +)
%-The previous job (marked -)
%tarThe job whose command starts with tar
%?backupThe job whose command contains backup
%1 and 1 are not the same
kill %1 means "job number 1 in this shell." kill 1 means "process ID 1" — on most systems that's the init process, and an ordinary user isn't allowed to signal it. Forgetting the % is a common and potentially confusing mistake.

Background Jobs and the Terminal

  • Output still appears. A background job's output is printed to your terminal, mixed in with whatever you're doing. Redirect it to a file to avoid this: long-command > out.log 2>&1 &.
  • Input stops the job. If a background job tries to read from the terminal, it's sent the SIGTTIN signal and stops, waiting for you to bring it to the foreground.
  • Leaving with stopped jobs. If you try to exit the shell while jobs are stopped, bash warns you. Exiting again anyway usually ends them.
Job control belongs to one shell
Job numbers only exist inside the shell that started the jobs. Another terminal, or a new login, has its own separate list — and when that shell goes away, so does its job list. That's exactly why Chapter 7 is needed.

Hands-On Exercises

Exercise 1

Start sleep 600 in the foreground, suspend it, resume it in the background, start a second sleep 900 &, then use jobs to identify the current and previous jobs. Finally, end both using job specs.

๐Ÿ“„ View solution
Exercise 2

Run read -p "Name? " name &. What does jobs show, and why? How do you finish the command?

๐Ÿ“„ View solution
Exercise 3

Start ping localhost in the foreground. Without stopping it permanently, get your prompt back so that it keeps running but stops cluttering your screen. What problem remains, and how would you have started it differently?

๐Ÿ“„ View solution

Chapter 5 Quick Reference

  • command & runs in the background and prints [job] PID
  • Ctrl-Z suspends the foreground job (SIGTSTP); Ctrl-C ends it (SIGINT)
  • jobs lists jobs (-r running, -s stopped); + is the current job, - the previous
  • fg/bg move jobs to the foreground/background; kill %n ends one; wait waits for all
  • Job specs: %n, %%/%+, %-, %string, %?string — never forget the %
  • Background jobs still print to the terminal, and stop (SIGTTIN) if they try to read from it
  • Job numbers belong to one shell and disappear with it