1
votes

Recently, I'm working on an script which used to launch job from file, assume the following job:

while true; do nc -l 8188 < index.html; done &

when I run it in an interactive shell, and I got an pid echo back like this:

[1] 31095

the pstree(1) output:

bash(31095, 31095) ---- nc(31096,31095)

both the while clause and the nc(1) command are in the same process group.

  1. When I type kill 30995, the while clause terminated as expected, but the nc(1) was left. I guess that kill statement just invoke the kill(2) system call.
  2. When I type kill %1, the entire 31095 process group was killed. I thing that may invoke killpg(2) internally.
  3. When I type 'fg' to bring the background to front, and then type 'Ctrl-C' to send the interrupt signal, then both the while clause and the nc(1) command gone, I think that's because the INT signal was sent to the process group as described in item 2.

I also download the bash-4.3-beta source code, but the source code is too much and I cannot find the related stuff. Could someone help me make my thoughts clear?

But when I put the above background job in script, kill %1 doesn't work as I guessed any more. Here is the script(kill2.sh):

while true; do
    nc -l 8888 < $0
done &

trap 'kill %1' INT TERM
wait || wait

I run this by bash kill2.sh, and then the pstree -pg 31835 result:

bash(31835, 31835) -- bash(31836, 31835) -- nc(31837, 31835)

when I type ctrl-c, 31835 and 31836 was killed, but nc was left. So I'm wondering if there's a special case for kill %1 in the script context?

1

1 Answers

0
votes
  1. When I type kill 30995, the while clause terminated as expected, but the nc(1) was left. I guess that kill statement just invoke the kill(2) system call.
  2. When I type kill %1, the entire 31095 process group was killed. I thing that may invoke killpg(2) internally.
  3. When I type 'fg' to bring the background to front, and then type 'Ctrl-C' to send the interrupt signal, then both the while clause and the nc(1) command gone, I think that's because the INT signal was sent to the process group as described in item 2.
  1. That's true.
  2. It might invoke killpg(), but at least on Linux, killpg() is implemented as a library function that makes the call kill(-pgrp, sig).
  3. True, if the terminal is the controlling terminal of a foreground process group, the Interrupt character will cause a SIGINT to be sent to this group.

But when I put the above background job in script, kill %1 doesn't work as I guessed any more. … So I'm wondering if there's a special case for kill %1 in the script context?

The jobspec %1 is only usable when job control is enabled. Job control is disabled by default for non-interactive shells. You can enable job control in the script by inserting the command set -m.