Job control (Unix): Difference between revisions

Content deleted Content added
I used 'unix-based' to mean 'unix and unix-like'
 
(8 intermediate revisions by one other user not shown)
Line 28:
 
==Foreground/background==
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 (since they can access the [[standard streams |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 {{endash}} where the processes cannot access interactive input and output 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==
[[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]].
[[POSIX]] specifies the interface to job control {{endash}} modeled on the Korn shell.<ref>{{man|cu|bg|SUS}}; {{man|cu|fg|SUS}}.</ref>. If a command line ends with {{code|&}}, then the job starts in the background. Command {{code|fg}} (short for foreground) causes a background job to move to the foreground; either the job specified or the one most recently added to 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 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> The foreground job can be paused by pressing {{keypress|Control|Z}} and when paused it can be resumed in the background via command {{code|bg}} (short for background). Command {{code|jobs}} reports information about each background job including ID, command line and running status.
 
; Start in background
The commands are typically implemented as [[shell builtin]]s; not separate [[computer program |programs]].
: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}}
:Command [[wait (command)|<code>wait</code>]] pauses the interactive session until the specified background jobs complete or for all background jobs of the active shell if none 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).
 
==ImplementationSignals==
{{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==