Um log num servidor em produção cresce ao segundo — e quase tudo o que interessa está numa das pontas: as últimas linhas dizem o que está a acontecer agora, as primeiras dizem quando tudo começou. É exatamente para isso que existem o tail e o head: ler o fim e o princípio de um ficheiro sem o despejar inteiro no terminal.
Neste artigo da série sobre comandos Linux, tratamos os dois em conjunto — porque são simétricos e porque, na prática, se usam lado a lado. Vamos das opções básicas ao tail -f, a ferramenta clássica de vigilância de logs em tempo real, e terminamos num simulador interativo onde pode acompanhar, ao vivo, a triagem de um ataque de força bruta a SSH.
O que fazem o tail e o head
Ambos leem ficheiros (ou o standard input) e escrevem uma parte deles no standard output: o head mostra o princípio, o tail mostra o fim. Sem opções, cada um imprime 10 linhas. Parece pouco, mas é a quantidade certa para responder à pergunta mais frequente de quem administra sistemas: «o que é que este serviço registou por último?»
tail [OPÇÕES] [FICHEIRO...]
head [OPÇÕES] [FICHEIRO...]
tail /var/log/auth.log # últimas 10 linhas
head /var/log/auth.log # primeiras 10 linhas
tail -n 50 servidor.log # últimas 50 linhas
tail -f /var/log/auth.log # segue o ficheiro ao vivo (Ctrl+C para sair)
Note que, em muitos sistemas, ler logs como o auth.log exige privilégios: o ficheiro pertence normalmente ao grupo adm, pelo que precisará de sudo ou de pertencer a esse grupo — um bom exemplo de privilégio mínimo aplicado aos próprios registos do sistema.
As opções que interessam
Escolher a janela de leitura
-n N— define quantas linhas mostrar.tail -n 50imprime as últimas 50;head -n 5, as primeiras 5. A forma abreviada histórica (tail -50) ainda funciona, mas-né a forma portável e legível.-n +N(só notail) — o sinal+muda o significado: em vez de «as últimas N», passa a «a partir da linha N até ao fim».tail -n +2é o idioma clássico para saltar a linha de cabeçalho de um CSV.head -n -N— com sinal negativo, oheadmostra tudo menos as últimas N linhas: o inverso exato do anterior.-c N— trabalha em bytes em vez de linhas.head -c 512 ficheiroé uma forma prudente de espreitar um ficheiro desconhecido sem arriscar despejar megabytes de binário no terminal.
Seguir um ficheiro ao vivo: -f e -F
O tail -f não termina quando chega ao fim do ficheiro: fica à espera e imprime cada linha nova no momento em que é escrita. É a forma mais direta de observar um serviço a funcionar — ou um ataque a decorrer. Há, porém, uma armadilha importante: o -f segue o descritor do ficheiro aberto. Quando o logrotate renomeia o auth.log para auth.log.1 e cria um ficheiro novo, o tail -f continua agarrado ao antigo — e emudece sem qualquer aviso.
tail -f /var/log/auth.log # segue o descritor: morre em silêncio na rotação
tail -F /var/log/auth.log # segue o NOME: reabre o ficheiro quando ele é substituído
tail -f --pid=1234 app.log # termina sozinho quando o processo 1234 acabar
O -F equivale a --follow=name --retry: vigia o nome do ficheiro e, quando este desaparece e reaparece, reabre-o e continua. Para monitorização contínua, a escolha certa é quase sempre -F. Complementos úteis: -s N ajusta o intervalo de sondagem em segundos e --pid encerra o tail quando um processo associado termina. Se quiser o melhor dos dois mundos — seguir ao vivo e poder parar para navegar no histórico — experimente less +F; e para os serviços que registam no journal do systemd, o equivalente é journalctl -f.
Vários ficheiros e pipes
- Com vários ficheiros, ambos os comandos imprimem cabeçalhos
==> nome <==antes de cada bloco.-qsuprime-os (importante em scripts) e-vforça-os mesmo com um único ficheiro. - O par natural do
tail -fé ogrep:tail -F log | grep padrãotransforma um rio de linhas num alerta focado. - Num pipe com mais estágios, use
grep --line-buffered: sem isso, ogrepacumula output em buffer e as linhas «ao vivo» chegam em blocos atrasados.
$ tail -F /var/log/auth.log | grep --line-buffered "Failed password"
Jul 28 11:57:12 srv01 sshd[2633]: Failed password for root from 203.0.113.45 port 54104 ssh2
Jul 28 11:57:19 srv01 sshd[2637]: Failed password for invalid user admin from 203.0.113.45 port 54121 ssh2
tail e head em cibersegurança
Deteção de força bruta em tempo real. Um ataque de password guessing a SSH deixa um rasto inconfundível no auth.log: sequências de Failed password e Invalid user vindas do mesmo endereço, com segundos de intervalo. tail -F auth.log | grep "Failed password" mostra a cadência do ataque no momento em que acontece — e filtrar pelo IP suspeito isola a atividade de um único atacante no meio do tráfego legítimo.
Resposta a incidentes. Durante a contenção de um incidente, é comum manter um terminal com tail -F sobre os logs críticos enquanto se atua noutro: cada ação do atacante — nova tentativa, nova sessão, novo erro — aparece de imediato. O fluxo em direto orienta as decisões: bloquear o IP na firewall, desativar uma conta, isolar a máquina.
Recolha de evidência. Para o relatório, tail -n 50 extrai as últimas linhas como registo do estado final, e head documenta o início do ficheiro — desde quando há registos e como era a atividade normal antes do ataque. Em ficheiros de origem desconhecida, head -c permite uma amostragem controlada sem executar nem despejar o conteúdo completo.
Monitorização que sobrevive à rotação. Muitos pipelines caseiros de alerta morrem em silêncio na primeira rotação de logs porque usam -f em vez de -F. É um erro com consequências de segurança reais: a vigilância pára precisamente sem avisar. Os coletores de logs profissionais resolvem este problema da mesma forma — seguindo o nome e o inode do ficheiro — e o tail -F é a versão de bolso desse mecanismo.
Experimente no simulador interativo
No simulador abaixo, o painel esquerdo mostra um auth.log fictício a crescer ao vivo — com um ataque de força bruta a decorrer — e o terminal executa o tail e o head sobre ele. Use Demonstrar tudo para seguir a triagem guiada completa do ataque, avance com Anterior/Seguinte, ou combine livremente as opções: -n, -n +10, -f, -F, o pipe com grep e a simulação de logrotate que mostra, lado a lado, porque é que o -f emudece e o -F sobrevive.
Erros comuns e boas práticas
- Usar
-fonde devia estar-F: em qualquer vigilância que dure mais do que alguns minutos, a rotação de logs vai acontecer — e o-fmorre em silêncio. Reserve o-fpara sessões curtas e interativas. - Esquecer o buffering do pipe: se o
tail -f | grepalimenta mais um estágio, as linhas podem ficar retidas.grep --line-buffered(oustdbuf -oL) resolve. - Confundir
-n Ncom-n +N:tail -n 10são as últimas 10 linhas;tail -n +10começa na linha 10 e vai até ao fim. Para saltar só o cabeçalho, é-n +2— não-n +1. - Contar com as 10 linhas por omissão: em logs movimentados, 10 linhas são segundos de história. Diga explicitamente quantas quer com
-n. - Cabeçalhos inesperados em scripts: ao processar vários ficheiros, os
==> nome <==entram no output e partem o parsing. Use-q. - Despejar binários: antes de aplicar
tailouheada um ficheiro desconhecido, confirme o tipo comfilee prefirahead -cpara amostrar com segurança.
Conclusão
O tail e o head são a primeira e a última página de qualquer ficheiro — e o tail -F | grep é, ainda hoje, a forma mais rápida de pôr um par de olhos em cima de um log em produção. Dominar a diferença entre -f e -F, o significado do -n +N e o buffering dos pipes transforma estes dois comandos simples numa ferramenta séria de monitorização e resposta a incidentes. Se quer levar estas competências mais longe, a HJFR oferece formação prática em Linux e cibersegurança e serviços de consultoria: explore o nosso catálogo de serviços e reveja também outros artigos da série, como o do comando useradd.
Este artigo faz parte da série «Comandos Linux, um a um» do blog HJFR — fique atento aos próximos comandos.
