Tutorial de Linux / PID e PPID: consultar processos e suas relações

O PID (process ID) identifica um processo; o PPID (parent process ID) identifica seu processo pai atual, que pode mudar se houver reparentalização. No Linux, esses números permitem localizar processos, examinar relações entre pais e filhos e selecionar um destino para sinais quando necessário. O kernel atribui os números: o que você administra é o processo identificado naquele momento, e não um número permanente.

Qual é a diferença entre PID e PPID?

Um processo é uma instância de um programa em execução. Iniciar o mesmo programa duas vezes normalmente cria dois processos com PIDs diferentes. Quando um processo cria outro, o filho passa a ter um PPID que aponta para seu pai. Essa relação descreve a hierarquia de processos, sem significar que o pai controla automaticamente todos os efeitos ou toda a duração do filho.

Campo Significado Uso principal
PID Identificador do próprio processo no contexto observado Selecionar um processo específico para consulta ou envio de sinal
PPID PID do pai atual do processo Examinar a relação entre pai e filho, considerando possíveis mudanças de pai

Por exemplo, se um shell tem PID 4250 e inicia um sleep com PID 4321, o PPID desse sleep pode ser 4250. Esses números são apenas ilustrativos. Um PID pode ser reutilizado depois que o processo anterior termina. Além disso, em ambientes com namespaces de PID, como contêineres, o mesmo processo pode ser visto com números diferentes conforme o local de observação.

Consultar o PID e o PPID de um processo

Os exemplos pressupõem Bash em Linux e o ps do procps/procps-ng, com suporte às opções mostradas. Outras implementações, como versões mínimas, podem ter opções diferentes. As consultas não exigem, por si só, acesso de administrador, mas a visibilidade dos dados depende das permissões e da configuração de /proc. No Bash interativo, $$ é expandido para o PID daquele shell:

ps -p "$$" -o pid,ppid,user,stat,etime,args

PID mostra o número do próprio shell e PPID o de seu pai atual. USER identifica o usuário, STAT mostra o estado, ELAPSED o tempo decorrido desde o início, e COMMAND ou ARGS a linha de comando. O tempo decorrido não é a mesma medida que o tempo de CPU consumido. Uma saída ilustrativa é:

    PID    PPID USER     STAT     ELAPSED COMMAND
   4250    4110 learner  Ss         00:42 -bash

Os números, o nome learner, o estado e o tempo acima não são valores que você deva reproduzir. Para um PID conhecido, a forma ps -p 4321 -o pid,ppid,args permite selecionar aquela identificação. Se o processo terminou e o PID ainda não foi reutilizado, não haverá uma linha correspondente. Se houver uma linha, confirme novamente a identidade: o número pode já pertencer a outro processo.

Para listar os processos atualmente visíveis, use ps -eo pid,ppid,user,stat,args; uma lista longa pode ser passada a less. Para pesquisar pelo nome, pgrep -a -x sleep pede correspondência exata do nome com -x e inclui a linha de comando com -a. Nesse padrão, -x não faz a pesquisa automaticamente pela linha de comando inteira. Vários processos podem ter o mesmo nome, então um resultado sozinho não prova que seja sua tarefa. Os guias de consulta de processos com ps e pesquisa de processos com pgrep detalham as opções.

Examinar pais e filhos sem encerrar processos

A aula de processos e gerenciamento de tarefas, em inglês apresenta a prática de criação e envio de sinais. Aqui, consulte o shell atual e seus filhos diretos, sem encerrar nenhum processo. --ppid seleciona os processos cujo pai tem o PID informado; não representa, sozinho, todos os descendentes da árvore.

ps -p "$$" -o pid,ppid,user,lstart,args
ps --ppid "$$" -o pid,ppid,stat,args

O próprio ps pode aparecer como um filho temporário. As consultas são fotografias de momentos diferentes: um processo pode terminar entre elas, e a lista não fica congelada enquanto você a examina. A coluna lstart acrescenta a data e o horário de início, úteis para conferir a identidade junto do nome e do usuário.

No Bash interativo, $$ identifica esse shell. Dentro de um subshell criado com parênteses, ele pode manter o valor do Bash que o iniciou; $BASHPID identifica o processo Bash atual. Por isso, não suponha que uma consulta a $$ dentro de parênteses esteja selecionando o novo subshell. Se estiver instalado, pstree -p "$$" oferece uma visualização opcional da árvore.

Distinguir namespaces de PID e reutilização de números

Um namespace de PID separa o espaço de identificação de processos. O mesmo processo pode ter um PID no contêiner e outro no host. Os comandos abaixo leem o identificador do namespace do shell e as identificações visíveis na hierarquia apresentada pelo sistema de arquivos proc montado naquele ambiente:

readlink "/proc/$$/ns/pid"
grep '^NSpid:' "/proc/$$/status"

readlink mostra o destino do link do namespace, normalmente no formato pid:[identificador]; esse identificador de namespace não é o PID do shell. A linha NSpid: apresenta identificadores nas camadas de namespaces visíveis a partir daquela montagem de proc. Tecnicamente, NSpid contém IDs de thread; para a thread principal do processo, eles coincidem com seus PIDs. O campo NStgid registra os IDs de grupo de threads, correspondentes aos IDs de processo.

Em um ambiente com uma única camada visível, pode haver apenas um número em NSpid. Configuração do kernel, versão, montagem de proc e permissões podem limitar a leitura ou a presença dos campos. Uma saída vazia ou uma falha de consulta não demonstra, sozinha, que exista ou não um contêiner. Se o pai está fora do namespace visível ao processo, seu PPID também pode ser apresentado como 0.

A diferença entre namespaces depende de onde você observa o processo. A reutilização de PID acontece em outro momento: um processo posterior recebe um número antes usado por outro que terminou. Não confunda os fenômenos nem misture números do host e do contêiner para selecionar o destino de um sinal.

O que acontece quando o pai termina?

Encerrar um pai não encerra necessariamente todos os seus filhos. Um filho que continua existindo pode passar a ter outro pai, processo conhecido como reparentalização; seu PPID pode mudar. Portanto, enviar um sinal ao PID de um pai não garante a limpeza de todos os processos abaixo dele. O comportamento também pode depender do gerenciador de serviços e de outras regras do ambiente.

Um filho que já terminou, mas cujo estado de saída ainda não foi recolhido, pode permanecer como processo zumbi. Ele já não executa trabalho; o sistema conserva informações para que o pai obtenha seu resultado. Repetir sinais KILL para esse PID não resolve a coleta pendente. Examine como o programa pai recolhe os filhos. No Bash, wait é o comando que pode aguardar e obter o estado de saída de um filho criado por aquele shell.

Trate o PID como uma identificação válida naquele contexto e naquele momento. Um arquivo de PID antigo ou uma anotação não bastam para escolher um processo a encerrar. Compare nome, usuário e horário de início, confira o namespace e revalide o destino próximo da ação. A consulta e uma ação posterior não formam uma operação atômica: o processo pode terminar nesse intervalo.

Como administrar processos de serviços?

Um serviço administrado pelo systemd pode receber outro PID ao reiniciar. Nesse caso, consulte e administre sua unidade de serviço em vez de tratar um PID antigo como identidade permanente. Em um sistema onde nginx.service realmente esteja instalado, systemctl status nginx.service mostra o estado da unidade. Use sudo systemctl restart nginx.service somente quando o reinício for necessário e apropriado para a operação: ele para e inicia a unidade e pode iniciar uma unidade que estava parada.

Se nginx não estiver instalado, ou se o ambiente usar outro gerenciador de serviços, confirme o nome e o método correto antes de agir. A aula de gerenciamento de unidades com systemctl explica essas operações. Um PID ajuda a localizar um processo específico; o PPID esclarece sua relação atual com o pai. Antes de interromper uma tarefa, restrinja a seleção e, para serviços gerenciados, use o gerenciador responsável.

Os manuais de namespaces de PID e dos campos de estado em proc explicam o contexto de observação e os campos NSpid e NStgid.

Fontes primárias

Os manuais ps(1), pgrep(1), pstree(1) e kill(1) descrevem as consultas e o envio de sinais. A documentação de parâmetros especiais do Bash e de comandos internos de controle de tarefas do Bash explica $$, $! e wait. Para processos encerrados e coleta de resultados, consulte wait(2); para unidades de serviço, consulte o manual oficial do systemctl.