1

I used to think that only if a shell supports job control, can it has the concept of "foreground" and "background" processes (group). But I read a paragraph indicating that's not true.

From APUE § 10.3 :

One specific example of this signal status behavior is how an interactive shell treats the interrupt and quit signals for a background process. With a shell that doesn’t support job control, when we execute a process in the background, as in

cc main.c &

the shell automatically sets the disposition of the interrupt and quit signals in the background process to be ignored. This is done so that if we type the interrupt character, it doesn’t affect the background process. If this weren’t done and we typed the interrupt character, it would terminate not only the foreground process, but also all the background processes.


Btw, given the example above,

If this weren’t done and we typed the interrupt character, it would terminate not only the foreground process, but also all the background processes.

It also seems to indicate that both the foreground processes and background processes can attach the same terminal at the same time. Is it true? Because I always think that the terminal can only attach to the foreground proccesses (group).

Rick
  • 1,157
  • At least for Linux, these concepts are rooted in the kernel, so no matter how shell is implemented, these concept always exist. Any process can basically have any terminal opened as an fd, but if that's the controlling terminal of its session, then behavior would be a little bit different with foreground or background. – 炸鱼薯条德里克 Mar 28 '19 at 15:47

1 Answers1

3

FWIW the concepts of "background process"[1], "controlling terminal"[2], and the & operator from the shell predate by years the concept of job control, which only appeared in 4.1BSD.

After job control was implemented and standardized, the behavior of background processes in shells without job control could be analyzed as some kind of "job control lite", where the ignoring of SIGINT and SIGQUIT, and redirecting of the stdin from /dev/null in pipelines started with & kind of mimics the behavior of background jobs (but not quite there ;-)).

It also seems to indicate that both the foreground processes and background processes can attach the same terminal at the same time. Is it true? Because I always think that the terminal can only attach to the foreground proccesses (group).

In a shell without job control, all processes (whether synchronous ("foreground") or asynchronous ("background") are actually running in the same process group (job), which is the same as that of the shell process, and can be a background or foreground job on the terminal.

Since all those processes will receive eg. a SIGINT from the kernel when the shell itself is in the foreground process group and ^C is typed on the terminal, their "background mode" is simulated by ignoring the SIGINT signal. The magic breaks when the commands started with & from a shell script install their own SIGINT handers.

Notice that shell scripts are usually run without job control, unless the set -m option is used.

[1] see "The Shell" chapter from the "Unix for Beginners" book, part of the Unix v6 distribution (1975).

[2] "controlling typewriter" in the kill(2) manpage of the same Unix v6.

  • So in a shell without job control, does it mean that foreground groups == background groups, and always attches to the current terminal/shell ? E.g. when I execute a "foreground" command like echo "hello", I can say I run this in the foreground, attached with the terminal, when I execute a command like echo "hello" &, now I can say I run this in the background, also attached with the terminal. – Rick Mar 28 '19 at 14:19
  • In a shell without job control there's a single process group, in which all the commands are run. If the shell is interactive, that process group is obviously the foreground one. It's not clear what you mean by "attached with the terminal": even with job control enabled, background jobs are still "attached" to the terminal (eg. the terminal is still their controlling terminal). If you want to run them completely detached from the terminal, you should start them with setsid(1) or such. –  Mar 28 '19 at 14:29
  • My bad, I realized that I made some mistakes in comments. OK, let me try again. With job control, it has the concepts : 1. foreground groups (foreground processes) 2. background groups(background processes), and they are not in the same group, shell generated signals only send to foreground groups. Without job control, it only has: 1. foreground groups (foreground processes and background processes are all in here). Shell generated signals only send to foreground groups, but under this situation, all foreground/background processes can catch these signals. – Rick Mar 28 '19 at 14:57
  • So the key is that either with job control or not, the concept of background processes and foreground processes still exists, as you mentioned at the beginning of your answer, they predate by years the concept of job control. – Rick Mar 28 '19 at 14:57
  • 1
    without job control, there is no concept of "process groups" (same thing as "jobs", at least in bsd/linux/posix). Without job control, the shell has no concept of any "groups" whatsoever -- but since that concept exists at OS level, its processes are still part of a process group, the same as that of the shell; and since it's the kernel which manages signals and ^C -> SIGINT translations, ignoring SIGINT in processes started with & makes the shell work in the way the users expect it to work -- until they try to fg bg jobs, or run a command which handles SIGINT itself :-) –  Mar 28 '19 at 15:19