Há muito menos IPC real em seu exemplo do que você pensa.
Quando bash
inicia o comando ps
, o processo ps herda várias coisas de seu processo pai: o arquivo manipula para entrada padrão, saída padrão e saída de erro padrão; configurações de ulimit; variáveis ambientais; e o diretório de trabalho atual, para citar alguns.
O comando ps
apenas grava sua saída no filehandle de saída padrão, que normalmente aponta para o dispositivo TTY do usuário, que é de responsabilidade do driver TTY do kernel. Em uma sessão de console (seja um console virtual do Linux ou um console serial real), isso se conectaria diretamente à tela do usuário; em sistemas modernos, o dispositivo TTY geralmente é um dispositivo escravo pseudo-TTY, que leva de volta a outro processo: esse processo pode ser um emulador de terminal em uma área de trabalho GUI local ou sshd
para logins remotos. O shell bash
que iniciou o comando ps
não será envolvido de forma alguma neste documento.
A única comunicação entre processos entre bash
e ps
em seu exemplo é bastante trivial: quando o processo ps
terminar, ele irá inicialmente para um estado "zumbi": a memória do processo é liberada , e seus únicos remanescentes serão o slot da tabela do processo e o código de retorno do processo ps
produzido na saída.
O kernel enviará um sinal SIGCHLD para o pai do zumbi, o processo bash
, que é wait(2)
para ele. Quando bash
receber o sinal, ele também receberá o código de retorno que o processo ps
produziu quando terminou. O shell o colocará na variável de shell especial $?
e emitirá um novo prompt de comando ou continuará o script em execução (se o comando ps
tiver sido iniciado a partir de um script).
Enquanto isso, como o código de retorno agora é entregue com sucesso ao processo pai, o kernel libera o slot da tabela de processo que o ps
costumava ocupar; e assim o processo zumbi foi colocado para descansar.