I have this simple script (pipecommand.sh
) that prints a prefix followed by its PID and PPID:
#!/usr/bin/env ksh
echo "$1: PID $$ PPID $PPID" >&2
And this script that prints its PID and PPID and makes a pipe:
#!/usr/bin/env ksh
echo "S: PID $$ PPID $PPID"
./pipecommand.sh A | ./pipecommand.sh B
When I run the script I get this output (I've simplified the PIDs):
S: PID 11 PPID 22
B: PID 33 PPID 11
A: PID 44 PPID 11
Okay, A and B are both children of the shell. Makes sense. Though I noticed that occasionally A's parent is /sbin/upstart --user
(in ubuntu 16.10 at least). Weird, but okay.
But when I run the pipe in the background (i.e. ./pipecommand.sh A | ./pipecommand.sh B &
) I get this output instead:
S: PID 11 PPID 22
B: PID 33 PPID 55
A: PID 44 PPID 33
Okay, so B's parent is upstart (PID 55). But A's parent is B (or randomly upstart as before)? What's going on? Is this a bug or is there some documentation somewhere explaining why this happens? This seems especially bad for programs that handle SIGCHLD in a specific way (which is how I came across this issue).
For comparison, in bash
A and B are children of the shell in the first case, and children of upstart in the second. These results seem to be consistent.
ksh --version
gives me: version sh (AT&T Research) 93u+ 2012-08-01
.
ksh93
executes the last (rightmost) pipeline command in the parent shell, whereasbash
executes all pipeline commands including the last command in a subshell. – fpmurphy Mar 23 '17 at 2:05