= Job control
:encoding: UTF-8
:lang: en
//:title: Yash manual - Job control
:description: This page describes yash's job control feature.

dfn:[Job control] is a function of the shell that executes multiple commands
simultaneously and suspends/resumes the commands.

When job control is active:

- Every link:syntax.html#pipelines[pipeline] executed by the shell becomes a
  dfn:[job].
  A job has its unique process group ID that is shared among all processes in
  the job.
- If the processes of a job are suspended while the shell is waiting for the
  processes to finish, the shell continues to the next command as if the
  process have finished.
  The shell remembers the job as suspended so that it can be resumed later.
- If a job is executed link:syntax.html#async[synchronously], the shell sets
  the foreground process group of the terminal to the process group of the
  job.
  When the job is finished (or suspended),
  the shell gets back to the foreground.
- The link:exec.html#subshell[subshell] executing a
  link:expand.html#cmdsub[command substitution] has its own unique process
  group ID like a job.
  However, the shell does not remember the subshell as a job,
  so it cannot be suspended or resumed.
- If the shell is link:interact.html[interactive], job status is reported
  before every command line prompt as if the command
  +link:_jobs.html[jobs] -n+ is executed.
- The standard input of an link:syntax.html#async[asynchronous command] is not
  automatically redirected to /dev/null.
- The shell does not exit when it receives the SIGTSTP signal.
- The value of the link:params.html#sp-hyphen[+-+ special parameter] contains
  +m+.
- When a job finished for which the link:_wait.html[wait built-in] has been
  waiting, the fact is reported (only if the shell is
  link:interact.html[interactive] and not in the
  link:posix.html[POSIXly-correct mode]).

When job control is inactive, processes executed by the shell have the same
process group ID as the shell.
The shell treats link:syntax.html#async[asynchronous commands] as an
uncontrolled job.

You can use the following built-ins to manipulate jobs:

link:_jobs.html[jobs]::
prints existing jobs
link:_fg.html[fg] and link:_bg.html[bg]::
run jobs in the foreground or background
link:_wait.html[wait]::
waits for jobs to be finished (or suspended)
link:_disown.html[disown]::
forgets jobs
link:_kill.html[kill]::
sends a signal to jobs

An interactive job-controlling shell reports jobs status before every prompt
by default.
You can set the following options to make the shell report status at other
timings:

link:_set.html#so-notify[notify]::
the shell reports immediately whenever job status changes.
link:_set.html#so-notifyle[notify-le]::
the shell reports immediately when job status changes while
link:lineedit.html[line-editing].

A job is removed from the shell's job list when:

- it has finished and the link:_jobs.html[jobs built-in] reported it,
- the link:_wait.html[wait built-in] successfully waited for the job to
  finish, or
- the link:_disown.html[disown built-in] removed the job.

Jobs are not removed from the list when an interactive shell automatically
reports the status of jobs.

[NOTE]
The word ``stop'' is synonymous to ``suspend'' in the context of job control.

[[jobid]]
== Job ID

Some link:builtin.html[built-in]s use the following notation, which is called
dfn:[job ID], to specify a job to operate on:

+%+::
+%%+::
+%&#43;+::
the current job
+%-+::
the previous job
+%{{n}}+::
the job that has job number {{n}}, where {{n}} is a positive integer
+%{{string}}+::
the job whose name begins with {{string}}
+%?{{string}}+::
the job whose name contains {{string}}

The dfn:[current job] and dfn:[previous job] are jobs selected by the shell
according to the following rules:

- When there is one or more suspended jobs, the current job is selected from
  them.
- When there is one or more suspended jobs other than the current job, the
  previous job is selected from them.
- The current and previous jobs are always different.
  When the shell has only one job, it is the current job and there is no
  previous job.
- When the current job finished, the previous job becomes the current job.
- When the current job is changed, the old current job becomes the previous
  job except when the old job finished.
- When the foreground job is suspended, the job becomes the current job.

Yash has some options
to modify the rules of the current/previous job selection.
(The rules above have priority over the options below.)

link:_set.html#so-curasync[cur-async]::
When a new link:syntax.html#async[asynchronous command] is started, it becomes
the current job.
link:_set.html#so-curbg[cur-bg]::
When a job is resumed by the link:_bg.html[bg built-in], the job becomes the
current job.
link:_set.html#so-curstop[cur-stop]::
When a job is suspended, it becomes the current job.

The current and previous jobs are not changed as long as the rules above are
met.

The rules of the current/previous job selection defined in the POSIX standard
are looser than yash's rules above.
Other POSIX-compliant shells may select the current and previous jobs
differently.

// vim: set filetype=asciidoc textwidth=78 expandtab:
