01 nov 2026 · linux, processos, rede, diagnostico · 6 min
Como ver processos, portas e conexões no Linux
Para descobrir o que está rodando, quem escuta em qual porta e qual processo segura um arquivo, use três ferramentas: ps, ss e lsof. Elas leem a mesma fonte, o diretório /proc do kernel, e respondem perguntas diferentes. ps fala de processos, ss fala de sockets, lsof fala de arquivos abertos. Juntas cobrem quase todo diagnóstico de “quem está fazendo o quê” numa máquina Linux.
ps: o que está rodando
ps é um retrato instantâneo. Ele não atualiza a tela como o top; imprime uma vez e sai. Isso o torna previsível para scripts e para colar em um chamado.
ps aux # todos os processos de todos os usuários
ps -ef # formato SysV, inclui PPID e hora de início
ps -e --forest # árvore de processos com indentação
ps -o pid,ppid,user,%cpu,%mem,stat,cmd -p 1234 # só o processo 1234
Para achar um processo pelo nome, prefira pgrep:
pgrep -a nginx # PID e linha de comando
ps aux | grep '[n]ginx' # o colchete evita que o próprio grep apareça
Colunas que vale a pena ler: PID, PPID, USER, STAT, %CPU, %MEM, TIME e CMD. O STAT diz o estado: R rodando, S dormindo, D esperando I/O (não pode ser interrompido), Z zumbi (processo morto cujo pai não leu o status) e T parado. Um D persistente costuma ser disco ou NFS travado, não CPU.
Para matar com segurança, use o PID que o ps mostrou e confira antes: kill -TERM <pid>, espere, e só depois kill -KILL <pid> se não sair. Matar pelo nome com killall ou pkill é prático, mas arrisca acertar o processo errado quando há mais de um com nome parecido.
ss: quem escuta em qual porta
ss substituiu o netstat e lê direto do kernel. A receita mais usada é ss -tlnp: TCP, só escuta, numérico, com processo.
ss -tlnp # TCP em escuta, com PID e nome
ss -ulnp # UDP em escuta
ss -tunap # tudo: escuta e conexões estabelecidas
ss -tn state established '( dport = :443 or sport = :443 )'
A saída tem quatro colunas que importam: State (LISTEN, ESTAB, TIME-WAIT), Local Address:Port, Peer Address:Port e Process. Se a coluna Process aparece vazia, rode com sudo ou verifique a capability net_admin do seu usuário.
Num contêiner de teste com um python3 -m http.server na porta 8080, o ss -tlnp mostra 0.0.0.0:8080 com users:(('python3',pid=381,fd=3)). O fd 3 é o descritor do socket. A mesma informação aparece no lsof, o que permite cruzar as duas visões.
ss -s imprime um resumo de contadores do kernel: quantas conexões em cada estado. Útil para ver se há acúmulo de TIME-WAIT ou de conexões semiabertas.
lsof: quem segura o arquivo ou a porta
lsof lista arquivos abertos. No Linux, socket, pipe e terminal também são arquivo, então lsof cobre rede. lsof -nP -iTCP -sTCP:LISTEN lista quem escuta, com a mesma informação do ss mais o caminho do executável.
lsof -nP -iTCP -sTCP:LISTEN # quem escuta em TCP
lsof -nP -i :8080 # quem usa a porta 8080 (TCP ou UDP)
lsof -p 381 # tudo que o processo 381 abriu
lsof /var/log/app.log # quem tem este arquivo aberto
lsof +D /tmp # desce o diretório /tmp
lsof +L1 # arquivos deletados mas ainda abertos
O caso do arquivo deletado é o mais valioso: um log rotacionado com mv ou rm continua ocupando espaço enquanto o processo o mantém aberto. lsof +L1 mostra esses fantasmas. A correção é reiniciar o serviço ou truncar o descritor via /proc/<pid>/fd/<n>.
lsof -b evita chamadas que podem bloquear (stat em NFS travado), útil quando a máquina está lenta e o lsof comum demora.
As três juntas
Pergunta: “quem está na porta 8080?”
ss -tlnp | grep ':8080'
lsof -nP -i :8080
Pergunta: “o que este processo faz?”
ps -p <pid> -o pid,user,lstart,cmd
lsof -p <pid> | head -30
Pergunta: “por que o disco encheu?”
lsof +L1
lsof / | grep deleted
A resposta quase sempre é um arquivo deletado ainda aberto, ou um processo escrevendo num caminho que ninguém vigia. Para aprofundar a caçada por espaço, veja disco cheio: como achar o que está ocupando.
Como verificar
Rode ss -tlnp numa máquina com ao menos um serviço escutando. A saída esperada tem uma linha com LISTEN, um endereço como 0.0.0.0:22 ou [::]:80, e a coluna Process preenchida. Se a coluna Process estiver vazia, o comando rodou sem privilégio suficiente.
Para confirmar o cruzamento, rode lsof -nP -iTCP -sTCP:LISTEN e confira que o PID e o nome do processo batem com o que o ss mostrou.
Se der errado
ss: command not found: o pacoteiproute2não está instalado. Em Debian ou Ubuntu,apt install iproute2. Em Alpine,apk add iproute2.lsof: command not found: instale comapt install lsofouapk add lsof. Algumas imagens mínimas não trazem.- ss não mostra o processo: rode com
sudoou verifique se o usuário tem a capabilitynet_admin. Sem isso, o kernel esconde o PID. - lsof demora muito: use
lsof -bpara pular stat bloqueante, ou restrinja com-p <pid>ou-i <porta>. - ps mostra processo que não existe mais: o retrato foi tirado antes do término; rode de novo.
ps, ss ou lsof
| Ferramenta | Responde | Lê | Quando usar |
|---|---|---|---|
| ps | quem está rodando, com CPU e memória | /proc//stat | inventário de processos, scripts |
| ss | quem escuta ou está conectado | /proc/net/tcp | portas, conexões, estados TCP |
| lsof | quem segura arquivo, socket ou porta | /proc//fd | arquivo travado, porta ocupada, disco fantasma |
Nenhuma substitui a outra. ps não sabe de porta, ss não sabe de arquivo, lsof não mostra CPU. O trio cobre o diagnóstico.
FAQ
ss ou netstat, qual usar hoje? Use ss. O netstat vem do pacote net-tools, que está em modo de manutenção e não acompanha mudanças recentes do kernel. O ss é o padrão nas distribuições atuais.
Por que o ss não mostra o nome do processo? Sem privilégio. Rode com sudo ou adicione a capability net_admin ao usuário. Em contêiner, verifique se a capability foi concedida.
lsof mostra muita coisa, como filtrar?
Combine seletores: lsof -p <pid> para um processo, lsof -u <user> para um usuário, lsof -i TCP:443 para uma porta. Seletores do mesmo tipo são OR; use -a para fazer AND entre tipos.
Como saber se um processo é zumbi?
ps aux | grep 'Z' na coluna STAT, ou ps -o pid,stat,cmd -p <pid>. Zumbi não consome CPU nem memória, mas ocupa PID. O pai precisa chamar wait() ou ser reiniciado.
O artefato abaixo roda sem ps, ss ou lsof. Por quê?
Porque os três leem /proc. O script lê os mesmos arquivos que eles leem, o que prova que a informação está no kernel, não na ferramenta. Em produção, use ps, ss e lsof; o script serve para entender e para ambientes mínimos.
Artefato
#!/usr/bin/env bash
# Receitas para descobrir processos, portas e arquivos abertos.
# Funciona lendo /proc diretamente: e o que ps, ss e lsof fazem por baixo.
# Rode como root para ver processos de outros usuarios.
set -euo pipefail
# demonstracao: abre uma porta de teste com perl (sem precisar de servico real)
perl -MIO::Socket::INET -e 'my $s=IO::Socket::INET->new(LocalPort=>8765,Listen=>5,Reuse=>1) or die $!; sleep 300;' >/dev/null 2>&1 &
DEMO_PID=$!
sleep 1
echo "=== 1. processos: quem esta rodando ==="
for d in /proc/[0-9]*; do
pid=${d##*/}
[ -r "$d/stat" ] || continue
nome=$(awk '{print $2}' "$d/stat" 2>/dev/null | tr -d '()') || continue
cmd=$(tr '\0' ' ' < "$d/cmdline" 2>/dev/null | sed 's/ *$//')
[ -z "$cmd" ] && cmd="[$nome]"
printf '%6s %-16s %s\n' "$pid" "$nome" "$cmd"
done | sort -n | head -12
echo
echo "=== 2. portas em escuta (equivale a ss -tlnp) ==="
decode_hex() {
local hex=$1
local iphex=${hex%:*} porthex=${hex#*:}
local a=$((16#${iphex:6:2})) b=$((16#${iphex:4:2})) c=$((16#${iphex:2:2})) d=$((16#${iphex:0:2}))
local port=$((16#$porthex))
printf '%s.%s.%s.%s:%s' "$a" "$b" "$c" "$d" "$port"
}
inode_para_pid() {
local alvo=$1
for fd in /proc/[0-9]*/fd/*; do
[ -L "$fd" ] || continue
if [ "$(readlink "$fd" 2>/dev/null)" = "socket:[$alvo]" ]; then
local pid=${fd#/proc/}; pid=${pid%%/*}
echo "$pid"
return
fi
done
}
awk 'NR>1 && $4=="0A" {print $2, $10}' /proc/net/tcp | while read -r endhex inode; do
pid=$(inode_para_pid "$inode")
printf '%-22s pid=%s\n' "$(decode_hex "$endhex")" "${pid:-?}"
done
echo
echo "=== 3. arquivos abertos por um PID (equivale a lsof -p) ==="
PID_ALVO=${1:-1}
echo "PID alvo: $PID_ALVO"
if [ -d "/proc/$PID_ALVO/fd" ]; then
for fd in /proc/$PID_ALVO/fd/*; do
[ -e "$fd" ] || continue
num=${fd##*/}
alvo=$(readlink "$fd" 2>/dev/null || echo "?")
printf ' fd %-4s -> %s\n' "$num" "$alvo"
done
else
echo " (processo $PID_ALVO nao existe)"
fi
# limpa a demonstracao
kill "$DEMO_PID" 2>/dev/null || true
wait "$DEMO_PID" 2>/dev/null || true
Para ver processos, memória e I/O em tempo real, veja como ver o que está consumindo a memória no Linux.
Fontes: ps(1), ss(8), lsof(8). Testado em contêiner debian:stable-slim em 01 nov 2026.