Job control (Unix)
In Unix and Unix-like operating systems, job control refers narrowly to control of jobs by a shell, especially interactively, where a "job" is a shell's representation for a process group. More broadly, it refers to any form of process management, not necessarily by the shell or via the job abstraction. Most simply this consists of suspending, resuming, or terminating execution of a job (i.e., all processes in the process group), but can also consist of sending other signals to the job. Job control is of particular interest in Unix due to its multiprocessing, and should be distinguished from job control generally, which is frequently applied to sequential execution (batch processing).
When using Unix or Unix-like operating systems via a terminal (or terminal emulator), a user will initially only have a single process running, their login shell. Most tasks[a] (directory listing, editing files, etc.) can easily be accomplished by letting the program take control of the terminal and returning control to the shell when the program exits – formally, by attaching to standard input and standard output to the shell, which reads or writes from the terminal, and catching signals sent from the keyboard, like Control+C.
However, sometimes the user will wish to carry out a task while using the terminal for another purpose – a task that is running but is not receiving input from the terminal is called a background job, while the single task that is receiving input from the terminal is called the foreground job. Job control is a facility developed to make this possible, by allowing the user to start processes in the background, send processes into the background, bring background processes into the foreground, and start and stop processes (formally, suspend, resume, and terminate).
The concept of "job" maps the (shell) concept of a single shell command to the (operating system) concept of the possibly many processes that the command entails. Concretely, a single task may consist of multiple processes: a given process may create additional child processes, which may in turn create their own child processes, etc., and a single shell command may consist of a pipeline of multiple communicating processes. These are managed by the OS as a single process group (they share a single process group ID or PGID), and the shell's internal representation of the process group is a job. This is defined in POSIX as:
A set of processes, comprising a shell pipeline, and any processes descended from it, that are all in the same process group.
A process group can thus be managed as a single entity by the shell, the job. A job in turn this can be referred to by a handle,[b], the job control job ID or simply job ID, which is used by shell builtins to refer to the job. Job IDs begin with the
%n identifies job n, while
%% identifies the current job. Other job IDs are specified by POSIX. In informal usage the number may be referred to as the "job number" or "job ID", and Bash documentation refers to the (%-prefixed) job ID as the jobspec.
Job control and job IDs are typically only used in interactive use, where they simplify referring to process groups; in scripting PGIDs are used instead, as they are more precise and robust, and indeed job control is disabled by default in bash scripts.
Job control was first implemented in the C shell by Jim Kulp, then at IIASA in Austria, making use of features of the 4.1BSD kernel. The Korn shell, developed at Bell Labs, adopted it and it was later incorporated into the SVR4 version of the Bourne shell, and exists in most modern Unix shells.
Typically, the shell keeps a list of jobs in a job table. Recall that a job corresponds to a process group, which consists of all the members of a pipeline and their descendents. The
jobs command will list the background jobs existing in the job table, along with their job number and job state (stopped or running). The
disown command can be used to remove jobs from the job table, converting them from jobs into daemons so that they continue executing when the user logs out.
A job running in the foreground can be stopped by typing the suspend character (Ctrl-Z). This sends the SIGTSTP signal to the process group. By default, SIGTSTP causes processes receiving it to stop, and control is returned to the shell. However, a process can register a signal handler for or ignore SIGTSTP. A process can also be paused with the SIGSTOP signal, which cannot be caught or ignored.
A stopped job can be resumed as a background job with the bg builtin, or as the foreground job with fg. In either case, the shell redirects I/O appropriately, and sends the SIGCONT signal to the process, which causes the operating system to resume its execution. In Bash, a program can be started as a background job by appending an ampersand (&) to the command line; its output is directed to the terminal (potentially interleaved with other programs' output), but it cannot read from the terminal input.
A background process that attempts to read from or write to its controlling terminal is sent a SIGTTIN (for input) or SIGTTOU (for output) signal. These signals stop the process by default, but they may also be handled in other ways. Shells often override the default stop action of SIGTTOU so that background processes deliver their output to the controlling terminal by default.
In Bash-compatible shells, the
kill builtin (not
/bin/kill) can signal jobs by job ID as well as by process group ID – sending a signal to a job sends it to the whole process group, and jobs specified by a job ID should be killed by prefixing "
%". Kill can send any signal to a job, however if the intent is to rid the system of the processes the signals SIGKILL and SIGTERM (the default), are probably the most applicable. A job running in the foreground can be permanently suspended by typing the kill character (Ctrl-C).
- Here "task" is a non-technical term for "some activity", while "process" and "job" are technical terms.
- A job ID is an abstract reference by the shell to a resource (a process group) managed externally, by the operating system, hence is a handle.
- Marshall Kirk McKusick and George V. Neville-Neil (2004-08-02). "FreeBSD Process Management: Process Groups and Sessions". The Design and Implementation of the FreeBSD Operating System. Addison Wesley. ISBN 0-201-70245-2.
- "Job Control", Bash Reference Manual