>_ josetilabs.com
← blog

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.

Terminal em dois paineis: ss -tlnp mostrando python3 pid 381 escutando em 0.0.0.0:8080, e lsof -nP -iTCP -sTCP:LISTEN confirmando o mesmo processo e fd 3
Saida real de um conteiner isolado com um python3 -m http.server na porta 8080.

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.

bash
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:

bash
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.

bash
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.

bash
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?”

bash
ss -tlnp | grep ':8080'
lsof -nP -i :8080

Pergunta: “o que este processo faz?”

bash
ps -p <pid> -o pid,user,lstart,cmd
lsof -p <pid> | head -30

Pergunta: “por que o disco encheu?”

bash
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

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

bash
#!/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.

Leia também

// Por e-mail

Os textos publicados aqui também vão por e-mail. O envio ainda não começou: quem deixar o endereço agora entra na primeira lista.

Guardo só o seu e-mail, a data e o registro desta autorização. Sem cookies, sem rastreador e nada compartilhado com terceiros. Detalhes na política de privacidade.