Como matar processos complexos em cascata no Linux com pkill sem deixar filhos orfãos
Voltar para blog

Como matar processos complexos em cascata no Linux com pkill sem deixar filhos orfãos

12/09/2026 · 4 min · Linux

Quem trabalha no terminal do Linux já passou por isso: você roda um ps aux | grep, localiza um serviço travado consumindo recursos ou prendendo portas, tenta matar pelo nome intuitivo e nada acontece. Ou pior: encerra o processo pai, mas os filhos continuam rodando em segundo plano como processos órfãos.

Recentemente, precisei lidar com essa situação ao gerenciar um serviço em background (antigravity-server) que executava uma hierarquia de processos encadeados em sh e node.

Abaixo, compartilho por que isso acontece no nível de kernel, a diferença entre os atributos de processos e o fluxo correto para encerrar tudo de forma cirúrgica.

1. O problema: identificando a árvore de processos e o estado sl#

Ao inspecionar a máquina para localizar os processos em execução:

ps aux | grep anti

A saída revelou três camadas encadeadas via fork/exec:

root      619129  0.0  0.0   2584   840 ?        S    15:22   0:00 sh /root/.antigravity-server/bin/1.21.9-hash/bin/antigravity-server --start-server --host=127.0.0.1 --port=0 --connection-token-file /root/.antigravity-server/.hash.token
root      619139  0.3  1.3 11876396 162812 ?     Sl   15:22   0:16 /root/.antigravity-server/bin/1.21.9-hash/node /root/.antigravity-server/bin/1.21.9-hash/out/server-main.js --start-server --host=127.0.0.1 --port=0 --connection-token-file /root/.antigravity-server/.hash.token
root      619356  0.2  0.6 1621680 76072 ?       Sl   15:22   0:14 /root/.antigravity-server/bin/1.21.9-hash/node /root/.antigravity-server/bin/1.21.9-hash/out/bootstrap-fork --type=ptyHost --logsPath /root/.antigravity-server/data/logs/20260405T152231
root      666120  0.0  0.0   6416  1936 pts/0    S+   16:48   0:00 grep anti

Na estrutura:

  1. PID 619129 (sh): O script wrapper inicial.
  2. PID 619139 (node ... server-main.js): O processo mestre da aplicação.
  3. PID 619356 (node ... --type=ptyHost): O worker forked para gerenciar terminais (PTY).

O significado do estado sl#

Na coluna STAT, a sigla Sl detalha a natureza da execução:

2. A armadilha do pkill convencional e a entrega de sinais no kernel#

Se executarmos apenas pkill antigravity, o comando falha silenciosamente.

Como a entrega de sinais funciona por baixo do capô#

  1. Varredura em /proc: O pkill busca entradas em /proc/[pid]/comm ou /proc/[pid]/cmdline.
  2. A Syscall kill(2): O utilitário dispara a syscall enviando o sinal padrão SIGTERM (15).
  3. Fila de sinais e task_struct: O kernel verifica permissões e enfileira o sinal no conjunto de sinais pendentes da estrutura task_struct do processo.
  4. Execução no User-Space: Quando a thread for escalonada ou retornar de uma chamada de sistema, ela processa o sinal.

No entanto, o /proc/[pid]/comm guarda apenas os primeiros 15 caracteres do nome do executável (sh ou node). A string antigravity-server existe apenas nos argumentos. Por isso, a flag -f (full command line) é obrigatória para casar toda a linha de comando.

3. Estratégias de encerramento seguro#

Estratégia 1: Varredura com pgrep e encerramento com pkill#

  1. Validação prévia com pgrep:
   pgrep -a -f "antigravity-server"
  1. Encerramento gracioso (SIGTERM):
   pkill -15 -f "antigravity-server"
  1. Encerramento forçado (SIGKILL como fallback):
   pkill -9 -f "antigravity-server"

Estratégia 2: Encerramento por grupo de processos (PGID)#

Para eliminar pai e filhos de uma só vez sem deixar órfãos, você pode enviar o sinal para todo o Process Group ID (PGID) usando o prefixo negativo:

kill -TERM -619129

Estratégia 3: Gestão nativa via systemd e Cgroups#

Em servidores em produção, a melhor prática é rodar o binário como uma Unit do Systemd:

[Service]
KillMode=control-group

Com KillMode=control-group, quando você executa systemctl stop servico, o Systemd envia sinais a todos os processos registrados naquele Cgroup específico, impedindo que workers gerados via fork() continuem soltos no sistema operacional.

4. O que acontece no kernel e casos especiais#

5. Validação pós-execução e descritores abertos#

Após o encerramento, verifique se sockets e descritores de arquivos foram totalmente liberados:

# Checar sockets e portas ativas
ss -tapen | grep -E '619139|619129'

# Listar descritores de arquivos abertos (caso ainda ativo)
ls -l /proc/619139/fd

# Se o processo estiver em execucao normal (S ou R), inspecione sinais com strace (se estiver em D-state/uninterruptible sleep, aguarde o kernel concluir o I/O)
strace -p 619139 -e trace=signal,exit_group,write

Conclusão: resumo prático e fluxo recomendado#

Para encerrar árvores de processos no Linux de forma definitiva:

  1. Valide o escopo com pgrep -a -f "padrao".
  2. Envie pkill -15 -f "padrao" ou kill -TERM -<PGID> para encerramento gracioso.
  3. Utilize pkill -9 -f "padrao" caso o processo não responda.
  4. Para serviços permanentes, utilize units do Systemd com KillMode=control-group.

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários