Unix & Linux
bash daemon jobs disown
Updated Mon, 15 Aug 2022 15:31:01 GMT

In bash, a process group is a job if and only if ...?


Here are two cases when a process group in an interactive shell isn't a job of the shell:

$ sleep 100 &
[1] 16081
$ jobs
[1]+  Running                 sleep 100 &
$ disown %1
$ jobs
$

and

$ ( sleep 200 & )
$ jobs
$ 

How does each case achieve making a process group not a job? In interactive bash, what is the necessary and sufficient condition for a process group to be a job of the shell?

The shell is a session leader running on a pseudoterminal slave. When the shell terminates, it will not affect the two sleep processes above, since they are not in the job list of the shell so don't receive SIGHUP. Then

  • do the two sleep processes still have the pseduoterminal slave as their session's controlling terminal?

  • What can terminate the two sleep processes, besides they exit normally or are killed by kill sending a signal?

I would like to know how different in effect the two cases are from a real daemon.




Solution

In both cases, the process group does start out as a job of the shell. When you call disown %1, the shell removes that entry from its list of jobs: that's the whole point of disown. With ( sleep 200 & ), the sleep process is a job of the subshell created by the parentheses; you can see that by running ( sleep 200 & jobs ). This one stops being the job of a shell when that shell exits; as with everything else, the subshell's jobs are its own, the parent never sees them.

The processes remain in the same session and still have the same controlling terminal. This has nothing to do with job control.

As with any process, they can be killed either by exiting or by receiving a signal. Since they aren't members of a foreground process group (and can't be, since the shell won't put them back into the foreground), they won't receive a kernel-generated SIGHUP if the terminal disappears.

A process group is a job of a shell if it started out as a job of that shell and it hasn't stopped being one. The details of what commands become separate jobs depends on the shell and is beyond the scope of this answer. In a nutshell, if a shell has job control enabled (which is the default if the shell is interactive), then each compound command is its own job. In particular:

  • A pipeline is a single job.
  • A command or process substitution is not a separate job, it runs in the original process group.
  • Anything running in the background (either started with & or backgrounded with Ctrl+Z) is a separate job.

A process group stops being a job if its leader exits, if the shell exits, or if the shell lets it go (with disown).