No primeiro exemplo, o shell com PID 100648 é seu shell interativo, enquanto sleep
é de fato o processo que substituiu bash -c ''
process. O execve()
syscall gera um novo programa que retém o PID do processo original que chamado, daí porque você não vê o original bash -c ''
lá. A razão simples de porque os comandos simples substituem o processo shell é porque ele economiza recursos, conforme explicado na resposta de Stephane .
Isso também é evidente em um teste simples em um terminal:
$ echo $$
10250
$ bash -c 'sleep 60'
E em outro:
$ pstree -p 10250
bash(10250)───sleep(21031)
Por que isso acontece dessa forma, é porque há apenas um comando simples sem canos e bash
executa execve direta para comandos simples .
Exatamente por esse motivo, bash
reconhece que você tem várias instruções de comando no segundo exemplo, portanto, para cada comando sleep
que você tem em "sleep 10000; sleep 99999 "
. No primeiro caso, execve()
pode apenas substituir o processo pai e quando as novas saídas - não há problema. Mas aqui o shell não pode sair após o primeiro comando ser concluído. Portanto, haverá fork e execve para sleep 10000
, que é o que você vê na saída de pstree
e, posteriormente, um novo fork e execve para sleep 99999
Outro teste que você pode realizar para acreditar que o comando simples em bash -c ''
substitui o processo shell é este:
$ bash -c 'grep "^Pid:" /proc/self/status /proc/$$/status'
/proc/self/status:Pid: 23946
/proc/23946/status:Pid: 23946
Note que esse comportamento é específico do bash. Para /bin/dash
em distros baseadas no Debian (e também evidente em strace
, também):
$ sh -c 'grep "^Pid:" /proc/self/status /proc/$$/status'
/proc/self/status:Pid: 24188
/proc/24187/status:Pid: 24187