Job control (Unix): Difference between revisions

Content deleted Content added
Edit for uniformity and accuracy; highlight diff between fg and wait
 
(21 intermediate revisions by one other user not shown)
Line 1:
{{Short description |Control of jobs byin a Unix shell}}
{{About |job control on a Unix-based system |the general computing term |job control (computing){{!}}job control}}
In a [[Unix]] or [[Unix-like]] [[operating system]], '''job control''' refers to controlling a [[process group]] as a [[job (computing)|job]] via a [[Unix shell| shell]].<ref>IEEE Std 1003.1-2001, [http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_201 Section 3.201, Job]</ref> Control features include suspend, resume, and terminate, and more advanced features can be performed by sending a [[signal (computing)|signal]] to a job. Job control allows a user to manage processing in the Unix-based [[multiprocessing]] environment, and is distinct from [[job control (computing)|general computing job control]].
 
[[POSIX]] specifies job control commands {{endash}} modeled after the Korn shell job control commands.<ref>{{man|cu|bg|SUS}}; {{man|cu|fg|SUS}}.</ref>. Command {{code|bg}} resumes the foreground job paused via {{keypress|Control|Z}} as a background job. Command {{code|fg}} causes the background job to run in the foreground; either the job specified or the one most recently sent the background if none specified. Command [[wait (command)|<code>wait</code>]] pauses the interactive session for the specified background jobs to complete or for all background jobs of the active shell if none is specified.<ref>{{cite web | last=Kerrisk| first=Michael |date=Feb 2, 2025 |title=wait(1p) — Linux manual page |website=man7.org |url=https://www.man7.org/linux/man-pages/man1/wait.1p.html |publisher= |access-date=May 13, 2025}} </ref>
 
Job control was first implemented in the [[C shell]] by Jim Kulp,<ref>
Line 21 ⟶ 19:
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.
 
==OverviewJob==
A job mapsencompasses toall aof singlethe processes that start for the handling of a shell [[command executionline]]. whichA simple command line may resultstart injust multipleone processesprocess, startingbut anda completing.command Multi-processline operationsmay comeresult aboutin multiple processes becausesince a process maycan create [[child processesprocess]]es, and a single shell command mayline consistcan ofspecify a [[Pipeline (Unix)|pipeline]] of multiple communicating processescommands. For example, the following command line selects lines containing the text "title", sorts them alphabetically, and displays the result in a [[terminal pager]]: <code>grep title somefile.txt | sort | less</code>. This creates at least three processes: one for [[grep|{{code |grep}}]], one for {{code |sort}}, and one for [[less (Unix)|{{code |less}}]]. Job control allows the shell to control these related processes as one entity, and when a user issues the appropriate key combination (usually {{keypress |Control|Z}}), the entire group of processes gets suspended.
In a shell, a user has one foreground job but can run multiple jobs in the background. 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 only possible via a foreground process. The user interactively enters a command and the implementation of the command (often a program) controls [[standard streams |input and output]] such that the user cannot access the shell until the command completes or the user interrupts it (i.e. via {{keypress|Control|C}}).
 
==Job ID{{anchor |job ID}}==
However, a user may wish to perform an operation while using the shell for another purpose. An operation that is running but not using the interactive input and output is running in the background. The single operation that is using the interactive input and output is running in the foreground. Job control is the facility to control how operations run as foreground or background. A user can start a process in the background, send a running processes to the background, bring a background process to the foreground, and suspend or terminate a process.
A job canis beidentified referredby toa bynumeric ''job ID'', a.k.a. ''job number'' which is classified as a [[Handle (computing)|handle]]{{efn|A jobsince IDit is an abstract reference by the shell to a [[computer resource |resource]] (a process group). managedAn externally,ID by the operating systemvalue, henceprefixed iswith a handle.}} called the ''job control job ID'' or simply ''{{visible anchorcode|job ID%}}'', whichcan isbe used bywith [[shella builtin]]sjob tocontrol refercommand to thespecify a job. AThe jobspecial IDreferences begin with the <{{code>|%%</code>}} character;and <{{code>|%n</code>+}} identifiesrefer jobto ''n'',the whiledefault <code>%%</code> identifiesjob; the currentone job.that Otherwould jobbe selected IDsif arenone specified by [[POSIX]].<ref>IEEE Std 1003.1-2001, [http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_203 Section 3.203, Job Control Job ID]</ref> In informal usage the number may be referred to as the "job number" or "job ID", and Bash documentation refers to thea reference (starting with {{code|%-prefixed}}) job ID as thea ''jobspec.'' (short for job specification).<ref>[https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html#Job-Control-Basics 7.1 Job Control Basics]</ref>
 
Job control and jobID IDsvalues are typically only used in an interactive use,shell. whereIn theyscripting, simplify referring to process groups; in scriptingPGID PGIDsvalues are used instead, as they are more precise and robust, and indeed job control is disabled by default in a bash scriptsscript.
A job maps to a single shell command execution which may result in multiple processes starting and completing. Multi-process operations come about because a process may create child processes, and a single shell command may consist of a [[Pipeline (Unix)|pipeline]] of multiple communicating processes. For example, the following command line selects lines containing the text "title", sorts them alphabetically, and displays the result in a [[terminal pager]]: <code>grep title somefile.txt | sort | less</code>. This creates at least three processes: one for [[grep|{{code |grep}}]], one for {{code |sort}}, and one for [[less (Unix)|{{code |less}}]]. Job control allows the shell to control these related processes as one entity, and when a user issues the appropriate key combination (usually {{keypress |Control|Z}}), the entire group of processes gets suspended.
 
==Foreground/background==
Jobs are managed by the operating system as a single [[process group]], and the job is the shell's internal representation of such a group. This is defined in [[POSIX]] as:<ref>IEEE Std 1003.1-2001, [http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_201 Section 3.201, Job]</ref>
By default, a job runs in the foreground where it uses [[standard streams |interactive input and output]]. The user enters a command line and interacts with the processes 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 {{endash}} where the processes cannot access interactive input but the user can perform other foreground operations while the background job runs concurrently. By default background jobs output to the interactive output stream which results in the interleaving of output from the foreground and background jobs although a user may [[Redirection (computing)|redirect]] output for a background job to prevent this.
 
==Control==
{{blockquote|A set of processes, comprising a shell pipeline, and any processes descended from it, that are all in the same process group.}}
[[POSIX]] specifies the [[user interface]] to job control {{endash}} modeled on the Korn shell.<ref>{{man|cu|bg|SUS}}; {{man|cu|fg|SUS}}.</ref>. The commands are typically implemented as [[shell builtin]]s; not separate [[computer program |programs]].
 
; Start in background
A job can be referred to by a [[Handle (computing)|handle]]{{efn|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.}} called the ''job control job ID'' or simply ''{{visible anchor|job ID}}'', which is used by [[shell builtin]]s to refer to the job. A job ID begin with the <code>%</code> character; <code>%n</code> identifies job ''n'', while <code>%%</code> identifies the current job. Other job IDs are specified by [[POSIX]].<ref>IEEE Std 1003.1-2001, [http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_203 Section 3.203, Job Control Job ID]</ref> 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.''<ref>[https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html#Job-Control-Basics 7.1 Job Control Basics]</ref>
:If a command line ends with {{code|&}}, then the job starts in the background.
; Pause foreground job
:The foreground job can be paused by pressing {{keypress |Ctrl| Z}}. In this state, a job can be resumed in the background via {{code |bg}} or resumed in the foreground via {{code |fg}}.
; Command {{code |fg}} {{anchor| fg}}
:Command {{code |fg}} (short for foreground) moves background job to the foreground; either the job specified or the one most recently added to the background if none specified. When the foreground job is paused (via {{keypress |Ctrl| Z}}), then this command resumes that job.
; Command {{code |wait}}
[[POSIX]] specifies job control commands {{endash}} modeled after the Korn shell job control commands.<ref>{{man|cu|bg|SUS}}; {{man|cu|fg|SUS}}.</ref>. Command {{code|bg}} resumes the foreground job paused via {{keypress|Control|Z}} as a background job. Command {{code|fg}} causes the background job to run in the foreground; either the job specified or the one most recently sent the background if none specified. :Command [[wait (command)|<code>wait</code>]] pauses the interactive session foruntil the specified background jobs to complete or for all background jobs of the active shell if none is specified.<ref>{{cite web | last=Kerrisk| first=Michael |date=Feb 2, 2025 |title=wait(1p) — Linux manual page |website=man7.org |url=https://www.man7.org/linux/man-pages/man1/wait.1p.html |publisher= |access-date=May 13, 2025}} </ref>
; Command {{code |bg}} {{anchor| bg}}
:Command {{code |bg}} (short for background) moves the paused foreground job to the background and resumes it.
; Command {{code |jobs}}
:Command {{code |jobs}} reports information about each background job including ID, command line and running status (stopped or running).
 
==Signals==
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.
 
==Implementation==
{{Unreferenced section|date=February 2020}}
The [[interprocess communication]] of job control is implemented via [[Unix signal |signal]]s.
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 (Unix)|pipeline]] and their descendants. The <code>jobs</code> command will list the background jobs existing in the job table, along with their job number and job state (stopped or running). When a [[login session|session]] ends when the user [[logout|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.
 
Typically, a shell maintains information about background jobs in a job table. When an [[login session |interactive session]] ends (i.e. user [[logout |logs out]]), the shell sends signal [[SIGHUP]] to all jobs, and waits for the process groups to exit before terminating itself. Some shells provide a non-POSIX command [[Disown (Unix)|<code>disown</code>]] that removes a job from the job table. The process group becomes an [[orphan process |orphan]]. The shell will not send it SIGHUP, nor wait for it to terminate. This is one technique for enabling a process as a [[daemon (computer software)|daemon]]; owned direclty by the root process [[init]]. The POSIX command [[nohup |{{code |nohup}}]] provides an alternate way to prevent a job from being terminated by the shell.
The [[Disown (Unix)|<code>disown</code>]] 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 process]]es, 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 [[daemon (computer software)|daemon]]s. Alternatives to prevent jobs from being terminated include [[nohup]] and using a [[terminal multiplexer]].
 
A job running inSuspending the foreground canjob be(via stopped{{keypress by|Ctrl typing the suspend character ([[Ctrl-|Z]]}}). This sends thesignal "SIGTSTP (terminal stop") to [[signalthe (computing)|signal]]processes ('''SIGTSTP''') toof the process group. By default, SIGTSTPthis signal causes processesa receiving itprocess to stop,pause andso controlthat isthe returnedshell tocan the shellresume. However, a process can registerignore athe signal handler for or ignore SIGTSTP. A process can also be paused withvia thesignal "stop" signalSIGSTOP ('''SIGSTOP'''stop), which cannot be caught or ignored.
 
A job running inWhen the foregrounduser canpresses be{{keypress interrupted|Ctrl by typing|C}}, the interruption character ([[Ctrl-C]]). Thisshell sends the "interrupt" signal ('''[[SIGINT (POSIX)|SIGINT]]''' (interrupt) to each foreground job process, which defaults to terminating the processit, though ita process can beignore overriddenthe signal.
 
When a stopped job is resumed (via {{code |bg}} or {{code |fg}}), the shell redirects [[Input/output]] and resumes it by sending signal SIGCONT to it.
A stopped job can be resumed as a background job with the <code>[[bg (Unix)|bg]]</code> [[shell builtin|builtin]], or as the foreground job with <code>[[fg (Unix)|fg]]</code>. In either case, the shell redirects [[Input/output|I/O]] appropriately, and sends the '''SIGCONT''' signal to the process, which causes the operating system to resume its execution. In [[Bash (Unix shell)|Bash]], a program can be started as a background job by appending an ampersand (<code>&</code>) 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 asignal '''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 shellsbash, the <code>[[kill (command)|kill]]</code> builtin (not <code>/bin/kill</code>) can signal jobs by job ID as well as by process group ID. – sendingSending a signal to a job sends it to the wholeeach process group,of andthe jobs specified by a job ID should be killed by prefixing <code>%</code>group. <code>kill</code> 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.
<!--
==See also==
-->
 
==Notes==
{{Notelist}}
-->
 
==References==