Jump to content

Job control (Unix)

From Wikipedia, the free encyclopedia
(Redirected from SIGTSTP)

In a Unix or Unix-like operating system, job control refers to controlling a process group as a job via a shell.[1] Control features include suspend, resume, and terminate, and more advanced features can be performed by sending a signal to a job. Job control allows a user to manage processing in the Unix-based multiprocessing environment, and is distinct from general computing job control.

Job control was first implemented in the C shell by Jim Kulp,[2] then at IIASA in Austria, making use of features of the 4.1BSD kernel. The KornShell, 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.

Job

[edit]

A job encompasses all of the processes that start for the handling of a shell command line. A simple command line my start just one process, but a command line may result in multiple processes since a process can create child processes, and a command line can specify a pipeline of multiple commands. For example, the following command line selects lines containing the text "title", sorts them alphabetically, and displays the result in a terminal pager: grep title somefile.txt | sort | less. This creates at least three processes: one for grep, one for sort, and one for less. Job control allows the shell to control these processes as one entity.

Job ID

[edit]

A job is identified by a handle[a] called the job control job ID, a.k.a. job ID, a.k.a. job number, which is used by shell builtins to refer to the job. A job ID begins with the % character; %n identifies job n, while %% identifies the current job. Other job IDs are specified by POSIX.[3] Bash documentation refers to the (%-prefixed) job ID as the jobspec.[4]

Job control and IDs are typically only used in an interactive shell. In scripting, PGIDs are used instead, as they are more precise and robust, and indeed job control is disabled by default in a bash script.

Foreground/background

[edit]

By default, a job runs in the foreground. The user enters a command line and interacts with the processes (since they can access the interactive input and output) but cannot issue another command until the current job terminates. Many operations (i.e. listing files) are relatively quick so the user can wait for a response with little down time and some operations (i.e. editing) require interaction that is only possible via a foreground job. But, if interaction is not required and the operation prevents access to the shell for a long time, the user may want to run it in the background. Job control allows the user to run a job in the background – where the processes cannot access interactive input and output but the user can perform other foreground operations.

Control

[edit]

POSIX specifies job control – modeled after the Korn shell job control commands.[5]. If a command line ends with &, then the job starts in the background. Command fg causes a background job to run in the foreground; either the job specified or the one most recently added to the background if none specified. Command wait pauses the interactive session for the specified background jobs to complete or for all background jobs of the active shell if none is specified.[6] The foreground job can be paused by pressing Control+Z and when paused it can be resumed in the background via command bg.

Implementation

[edit]

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 descendants. The jobs command will list the background jobs existing in the job table, along with their job number and job state (stopped or running). When a session ends when the user logs out (exits the shell, which terminates the session leader process), the shell process sends SIGHUP to all jobs, and waits for the process groups to end before terminating itself.

The disown command can be used to remove jobs from the job table, so that when the session ends the child process groups are not sent SIGHUP, nor does the shell wait for them to terminate. They thus become orphan processes, and may be terminated by the operating system, though more often this is used so the processes are adopted by init (the kernel sets their parent process to init) and continue executing as daemons. Alternatives to prevent jobs from being terminated include nohup and using a terminal multiplexer.

A job running in the foreground can be stopped by typing the suspend character (Ctrl-Z). This sends the "terminal stop" signal (SIGTSTP) 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 "stop" signal (SIGSTOP), which cannot be caught or ignored.

A job running in the foreground can be interrupted by typing the interruption character (Ctrl-C). This sends the "interrupt" signal (SIGINT), which defaults to terminating the process, though it can be overridden.

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.

Notes

[edit]
  1. ^ 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.

References

[edit]
  1. ^ IEEE Std 1003.1-2001, Section 3.201, Job
  2. ^ Foreword by Bill Joy in Anderson, Gail; Paul Anderson (1986). The UNIX C Shell Field Guide. Prentice-Hall. p. xvii. ISBN 0-13-937468-X.
  3. ^ IEEE Std 1003.1-2001, Section 3.203, Job Control Job ID
  4. ^ 7.1 Job Control Basics
  5. ^ bg – Shell and Utilities Reference, The Single UNIX Specification, Version 5 from The Open Group; fg – Shell and Utilities Reference, The Single UNIX Specification, Version 5 from The Open Group.
  6. ^ Kerrisk, Michael (Feb 2, 2025). "wait(1p) — Linux manual page". man7.org. Retrieved May 13, 2025.

Further reading

[edit]
[edit]