É a casca; como você verá por meio do comando ps
, nesse caso, o PPID de less
será o PID do shell.
Os processos ls
e less
não têm muito em comum; é só que o stdout do primeiro é canalizado no stdin do último.
Considere este comando no shell: ls|less
Agora sabemos que ls
e less
são executados como dois processos diferentes. Sabemos que o shell se bifurca e cria um processo filho que carrega o programa ls
usando uma das famílias de funções exec()
.
Minhas perguntas são: quem bifurca o processo que executa o comando less
? É o shell ou o processo que está executando o comando ls
?
É a casca; como você verá por meio do comando ps
, nesse caso, o PPID de less
será o PID do shell.
Os processos ls
e less
não têm muito em comum; é só que o stdout do primeiro é canalizado no stdin do último.
Algumas experiências:
$ yes | sleep 10m &
[1] 32395 32396
$ pstree -pa $(ps -o ppid= -p $(pgrep yes))
zsh,29630
├─pstree,32402 -pa 29630
├─sleep,32396 10m
└─yes,32395
Como pode ser visto, o pai de ambos os processos é o shell.
Com um pipeline mais longo:
$ sleep 10m | sleep 10m | sleep 10m | sleep 10m &
[1] 32320 32321 32322 32323
$ pstree -pa $(ps -o ppid= -p $(pgrep sleep -o))
zsh,29630
├─pstree,32498 -pa 29630
├─sleep,32473 10m
├─sleep,32474 10m
├─sleep,32475 10m
└─sleep,32476 10m
De fato, os processos ainda são todos filhos do shell.
Com um subnível:
$ sleep 10m | ( sleep 10m | sleep 10m ) | sleep 10m &
[1] 595 596 597
$ pstree -pa $(ps -o ppid= -p $(pgrep sleep -o))
zsh,29630
├─pstree,610 -pa 29630
├─sleep,595 10m
├─sleep,597 10m
└─zsh,596
├─sleep,598 10m
└─sleep,599 10m
Isso depende do shell que você está usando.
Tente ligar:
yourshell -c 'echo bla | read VAR; echo $VAR'
e verifique o que é impresso. Outra verificação é executar:
yourshell -c 'ps -f| more'
com diferentes shells e veja o PID e o PPID.
Cada shell usa seu próprio método diferente.
Naqueles shells que fazem fork para seções de um pipeline, é praticamente sempre a criança que faz o fork. Isso é praticamente todo o trabalho. Exceto que a criança geralmente não sobrevive, e é normalmente substituída pelo processo chamado.
sh -c 'echo "$$"
sh -c "echo \"\$PPID\"" |
cat'
14546
14546
... mas se você apenas der à criança qualquer coisa para fazer ...
sh -c 'echo "$$"
{ sh -c "echo \"\$PPID\""; :; } |
cat'
14556
14557
... está por aí. Você não tem que suportar isso, no entanto.
sh -c 'echo "$$"
{ exec sh -c "echo \"\$PPID\""; :; } |
cat'
14563
14563