Comando watch no Linux: intervalo, diff e pipes
Aprenda a usar o watch no Linux: ele repete comandos a cada 2 segundos por padrão. Ajuste o intervalo, destaque diferenças, saia ao mudar e proteja pipes.
O que o comando watch faz
O comando watch executa novamente outro comando num intervalo fixo e redesenha a respetiva saída no mesmo local do ecrã. O intervalo predefinido é de dois segundos. Use-o quando estiver à espera que um valor se altere: um disco a encher, um contentor a estabilizar, uma renovação de certificado a ser concluída ou uma fila a esvaziar.
O watch faz parte do procps-ng e já está instalado numa VPS Ubuntu ou Debian acabada de criar, como parte do pacote procps. Confirme a sua versão antes de confiar em qualquer opção abaixo, porque duas das opções úteis são recentes.
watch --versionNo Ubuntu 24.04, isto apresenta uma linha semelhante a watch from procps-ng 4.0.4. Agora, o exemplo útil mais simples.
watch df -h /O ecrã é limpo e apresenta uma linha de cabeçalho, uma linha em branco e, depois, a saída de df -h /:
Every 2.0s: df -h / server1: Sun Aug 9 10:21:44 2026À esquerda está o intervalo e o comando exato que o watch está a executar. À direita estão o nome do host e a hora atual. O relógio é a parte útil, porque confirma que o ecrã continua a ser atualizado quando os valores abaixo não se alteram. Prima Ctrl+C para sair.
O watch desenha um quadro que cabe no terminal. As linhas longas são quebradas, o -w trunca-as em vez disso, e tudo o que ultrapasse a última linha não é desenhado. Não existe scrollback dentro do quadro, porque cada ciclo substitui o anterior. Esse facto determina a maior parte das situações em que o watch é útil.
Com que frequência o watch deve voltar a executar o comando?
Dois segundos são apenas o valor predefinido. Escolha o intervalo com base na rapidez com que o valor muda e no custo de cada execução.
-n 0.5para contadores que mudam constantemente, comoss -sou a contagem de bytes de uma interface. O menor intervalo aceite pelo watch é de 0.1 segundos.-n 30ou-n 60para discos e certificados. Um sistema de ficheiros que fica cheio ao longo de um dia não precisa de trinta atualizações por minuto.
O watch executa o comando, espera que este termine e só depois aguarda durante o intervalo. O tempo de execução é acrescentado à pausa. Assim, um comando que demora oito segundos com -n 2 produz uma atualização a cada dez segundos e mantém a máquina ocupada durante todo esse tempo. Adicione -p (--precise) para que o watch tente iniciar uma execução a cada intervalo de segundos. A medição é feita entre o início de uma execução e o início da seguinte.
Se quiser sempre um valor predefinido diferente, exporte WATCH_INTERVAL no perfil da sua shell. Um -n explícito continua a ter prioridade. Execute watch --help para confirmar que a sua compilação lê essa variável.
Destaque o que mudou com -d
Ler uma parede de texto idêntico para encontrar o campo que mudou dá trabalho. -d (--differences) faz isso por si.
watch -n 30 -d 'df -h / /var'Os caracteres que diferem do quadro anterior são apresentados em vídeo inverso. Assim, a célula Use% fica destacada no momento em que muda, enquanto todo o resto permanece sem alterações. Se /var não for um sistema de ficheiros separado, verá o sistema de ficheiros raiz listado duas vezes. Esta é uma forma rápida de perceber como o sistema foi particionado.
A comparação é posicional. Isto significa que watch alinha o novo quadro com o anterior e compara os caracteres um a um. Saídas cujas colunas mudam de largura ficam quase todas destacadas. Por isso, prefira comandos com um formato estável. As versões atuais do procps-ng também aceitam watch --differences=permanent. Esta opção mantém destacados todos os locais que já mudaram, em vez de destacar apenas a alteração mais recente. Confirme-o com watch --help antes de depender deste comportamento.
Como faço o watch terminar quando o resultado mudar?
-g (--chgexit) faz o watch terminar na primeira vez que o resultado for diferente do da execução anterior. O prompt volta a aparecer, por isso pode colocar algo depois dele na mesma linha.
watch -n 10 -g 'systemctl is-active myapp' ; echo 'state changed'Esta é a opção que transforma o watch numa ferramenta para "avisar quando a implementação terminar". Existe uma armadilha, e ela apanha toda a gente: a comparação abrange todo o resultado. Por isso, qualquer relógio ou PID (identificador de processo) incluído nele muda logo na primeira atualização, e o watch termina imediatamente. systemctl status myapp mostra o tempo decorrido e o uso de memória, portanto -g não tem utilidade nesse caso. Reduza o comando ao único facto estável que está a aguardar. É isso que systemctl is-active fornece.
As versões mais recentes do procps-ng adicionam o teste oposto, --equexit <cycles>, que termina depois de o resultado permanecer igual durante esse número de ciclos. Ele responde a "avise-me quando isto ficar sem alterações". Consulte watch --help, porque as versões mais antigas não incluem esta opção.
Por que watch ignora o meu pipe e o meu glob?
Este é o erro que quase toda a gente comete uma vez. A causa está na shell, não no watch.
watch docker compose ps | grep webA shell interativa lê a linha inteira antes de executar qualquer coisa e divide-a no pipe. Inicia watch docker compose ps e liga a saída do próprio ecrã do watch a grep. O watch deixa de escrever num terminal, por isso a apresentação fica incorreta ou vazia, e grep filtra a saída das atualizações em vez de uma lista de contentores.
Coloque todo o pipeline entre aspas para que seja recebido como um único argumento.
watch 'docker compose ps | grep web'O watch passa essa string a sh -c, e essa shell executa o pipeline uma vez por ciclo. Os globs seguem a mesma regra, mas com um sintoma menos evidente.
watch ls -l /var/log/*.log
watch 'ls -l /var/log/*.log'A primeira linha expande o glob uma vez, na sua shell, no momento em que prime Enter. O watch volta então a executar uma lista de nomes de ficheiros fixa, por isso um ficheiro de log criado um minuto depois nunca aparece. A segunda linha entrega o glob ao watch, que o expande dentro de sh em cada ciclo, fazendo com que os ficheiros novos apareçam automaticamente.
As aspas também determinam quando uma variável ou uma substituição de comando é avaliada. watch "echo $(date)" executa date uma vez, na sua shell, e depois repete essa string fixa indefinidamente. watch 'echo $(date)' executa date em cada ciclo. As aspas simples significam mais tarde. As aspas duplas significam agora.
Há mais duas consequências desse sh -c:
- Os aliases e as funções da shell não existem dentro dele.
watch llfalha comsh: 1: ll: not found, porquesh -cnunca lê o seu.bashrc. Escreva o comando real ou indique o caminho completo para um binário que só esteja no seuPATHinterativo. - Vale a pena capturar a saída de erro. Coloque
2>&1dentro das aspas quando quiser que o texto de erro seja apresentado no quadro, em vez de ficar espalhado pela saída.
Quando as aspas se tornam difíceis de gerir, -x (--exec) executa o comando diretamente, sem passar por sh -c. Os argumentos com espaços tornam-se mais fáceis de tratar, mas os pipes e os globs deixam de funcionar completamente, porque já não existe uma shell para os interpretar.
Os privilégios seguem a mesma lógica, porque o watch é um processo normal. watch 'sudo ss -tulpn' apresenta um pedido de palavra-passe que não consegue ver nem preencher. Execute sudo watch 'ss -tulpn' em vez disso e lembre-se de que todo o ciclo será executado como root até premir Ctrl+C.
Quatro aspectos que vale a pena monitorizar num VPS
Um disco que está a ficar cheio
watch -n 30 -d 'df -h / /var'df pede ao kernel valores que este já mantém, por isso é suficientemente barato para ser repetido indefinidamente. du -sh /var/log não é, porque percorre todos os ficheiros da árvore em cada ciclo. Com watch, lê o disco continuamente e abranda a máquina que está a tentar diagnosticar. Execute du uma vez ou use ncdu e deixe df sob watch para saber se o número continua a aumentar.
Um contentor que reinicia continuamente
cd /srv/myapp
watch -n 5 -d 'docker compose ps'A coluna de estado mostra há quanto tempo cada contentor está ativo. Um contentor num ciclo de falhas repõe continuamente o estado para "Up 2 seconds", e -d torna isso evidente à primeira vista. Mude primeiro de diretório, porque watch herda o diretório de trabalho da shell que o iniciou e docker compose precisa do diretório do projeto. watch informa que está a ocorrer um reinício. docker compose logs -f web informa porquê. Depois de saber a causa, registe a solução como um healthcheck do Compose que reinicia o contentor por si para que ninguém tenha de ficar a olhar para um ecrã.
A chegada de uma renovação de certificado
sudo -i
watch -n 60 -g 'openssl x509 -noout -enddate -in /etc/letsencrypt/live/example.com/fullchain.pem'O comando imprime uma linha, notAfter=Nov 7 09:14:22 2026 GMT, e nada mais, por isso -g é executado exatamente quando o ficheiro é substituído por um ficheiro renovado. Os ficheiros em /etc/letsencrypt/live só podem ser lidos por root, razão pela qual isto é executado numa shell root. Tenha em atenção que este comando monitoriza o certificado no disco. Um servidor web em execução mantém o certificado antigo em memória até ser recarregado, por isso confirme o que está realmente a ser servido com echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate e não execute esse comando a cada dois segundos contra um host público. A renovação propriamente dita pertence a um serviço e temporizador do systemd, e systemctl list-timers mostra quando será executada novamente.
Uma fila a ser esvaziada
watch -n 15 'postqueue -p | tail -n 1'Isto imprime uma linha de resumo como -- 24 Kbytes in 6 Requests. ou Mail queue is empty quando termina. O mesmo formato funciona para qualquer fila que possa contar: watch -n 5 'find /srv/queue/incoming -type f | wc -l'.
Aqui, watch atinge o seu limite. Compara cada estado com o estado anterior e não consegue testar uma condição, por isso nunca pode informar que "a contagem chegou a zero". Um ciclo de shell simples consegue fazê-lo, usando substituição de comandos para guardar a contagem em cada passagem:
until [ "$(find /srv/queue/incoming -type f | wc -l)" -eq 0 ]; do sleep 5; done; echo 'queue drained'Quando o comando watch é a ferramenta errada
watch executa novamente o seu comando sem memória da execução anterior e sem saber o que esse comando faz. Isso é adequado para df. É inadequado em quatro situações.
- Logs. watch redesenha um quadro fixo, por isso as linhas que aparecem e saem do ecrã entre dois ciclos são perdidas. Use
journalctl -fu nginxoutail -f, que transmitem as linhas novas à medida que são escritas. - Comandos dispendiosos.
du -sh /ou uma consulta a uma base de dados ocupada tornam-se uma carga permanente em segundo plano, em qualquer intervalo, porque watch continua a iniciá-los. - Qualquer operação com efeitos secundários. Um comando que escreve, envia, reinicia ou instala fará isso novamente em cada ciclo. Um
curlcontra uma API a cada dois segundos representa 43,200 pedidos por dia, o que pode levar à suspensão de uma chave de API gratuita. - Verificações de longa duração. watch é executado no seu terminal e termina com a sua sessão. Não alerta ninguém e não mantém histórico depois de fechar o portátil. Para isso, use um monitor de estado real, como o Uptime Kuma ou uma verificação agendada que permaneça no servidor.
O limite correto é o tempo. watch serve para os dez minutos que passa à espera que algo específico aconteça. Qualquer verificação que deva continuar amanhã pertence a um temporizador agendado ou a um monitor real.
Executar watch dentro do tmux quando estiver ligado por SSH
Por SSH, o watch só é tão persistente quanto a ligação. Quando a ligação cai, a shell recebe SIGHUP e encerra o watch com ela. O tmux resolve esse problema e torna o watch realmente útil num servidor remoto.
tmux new -As ops
watch -n 30 -d 'df -h /'Prima Ctrl+b e depois d para desanexar. O ciclo continua a ser executado no servidor. Ligue-se novamente mais tarde com tmux attach -t ops e o quadro continuará a ser atualizado; o relógio do cabeçalho confirma isso. Divida a janela para manter watch de um lado e journalctl -f do outro. Esta é a ideia central de um ambiente de trabalho de terminal baseado em tmux. Quando a mesma questão se aplica a vários servidores em simultâneo, use uma ferramenta criada para gerir vários servidores Linux em vez de ocupar o ecrã com vários painéis do watch.
Os ecrãs apresentados aqui são meramente ilustrativos. A disposição das colunas e as cadeias de versão variam entre distribuições e versões do procps-ng. Por isso, consulte man watch na sua própria máquina para confirmar as flags realmente disponíveis na sua compilação.
FAQ
Por que o watch ignora o pipe em watch mycmd | grep foo?
O seu shell divide a linha no pipe antes de o watch arrancar. Assim, encaminha o desenho do próprio ecrã do watch para grep, e a saída do comando nunca é filtrada. Coloque todo o pipeline entre aspas: watch 'mycmd | grep foo'. O watch passa esse único argumento a sh -c, que executa o pipeline uma vez por ciclo. A mesma regra aplica-se a globos e à substituição de comandos.
Que intervalo devo usar com o watch?
Adapte-o à velocidade a que o valor varia e ao custo de cada execução. Meio segundo é adequado para contadores rápidos, e 0.1 segundos é o intervalo mínimo aceite pelo watch. Trinta a sessenta segundos são adequados para discos e certificados. O tempo de execução do comando é acrescentado à pausa, exceto se passar -p. Assim, um comando lento com -n 1 é executado continuamente, sem pausas.
O watch pode acompanhar um ficheiro de log?
Não. O watch redesenha um único quadro e não mantém histórico. Por isso, qualquer linha que apareça e saia do ecrã entre dois ciclos perde-se definitivamente. journalctl -fu <unit> e tail -f transmitem as linhas novas à medida que aparecem, que é o comportamento necessário para logs. Use o watch para valores que tenham um estado atual, como uma percentagem de disco ou o comprimento de uma fila.
Como faço o watch parar quando ocorre o evento que estou a aguardar?
Use -g (--chgexit) e indique um comando cuja saída permaneça idêntica até esse evento. Uma saída que contenha um relógio ou um PID muda na primeira atualização e termina imediatamente. Por isso, systemctl is-active myapp funciona quando systemctl status myapp não funciona. Para uma condição real, como uma contagem chegar a zero, use um ciclo until do shell, porque o watch só consegue detetar que a saída mudou.
Por que o watch indica command not found para algo que funciona no meu shell?
O watch passa o comando a sh -c, e esse shell não lê .bashrc. Por isso, os seus aliases e funções do shell não existem nesse contexto. A mensagem costuma ser sh: 1: ll: not found. Escreva o comando real ou use o caminho completo para um binário que só esteja disponível no seu PATH interativo.