Este artigo explica como repetir um comando a cada X segundos no Linux, de duas maneiras: usando watch e usando sleep em um loop de execução while (com uma maneira de evitar flutuação de tempo ao usar comandos em loop longos).

watch para executar um comando a cada X segundoswatch pode executar um comando repetidamente, exibindo sua saída e erros (a primeira tela cheia). Isso permite que você observe a mudança de saída do programa ao longo do tempo.
Usando watch para executar um comando a cada X segundos:
watch -n
Onde:
-n especifica o intervalo de tempoX é o intervalo no qual executar o comando, em segundos (com 0,1 segundos sendo o menor valor possível)comando é o comando que você deseja executarSe o comando contiver barras verticais, aspas ou outros caracteres especiais, use aspas simples, por exemplo: 'comando'.
Exemplo. O seguinte comando executa ps aux | grep firefox a cada 5 segundos:
watch -n 5 'ps aux | grep firefox'
O comando watch tem algumas opções, como destacar as diferenças entre atualizações sucessivas (--differences/-d), beep se um comando tem uma saída diferente de zero (--beep/-b), e muito mais. Verifique sua página man para obter mais informações.
Você também pode gostar de: Como encontrar arquivos modificados nos últimos N dias ou minutos usando find
sleep em um loop while para repetir um comando a cada X segundosOutra maneira de repetir um comando a cada X segundos no Linux é usar um loop while com o comando sleep:
while true; do
Aqui, você precisa substituir comando com o comando a ser executado e X com o intervalo de tempo em segundos (o número não precisa ser um inteiro, mas não pode ser negativo; você também pode especificar minutos - 1m por exemplo, horas - 1h por exemplo, etc. .).
Exemplo. O seguinte one-liner executa o comando echo $(date) a cada 5 segundos:
while true; do echo $(date); sleep 5; done
Se você estiver fazendo algo mais complicado, certifique-se de que o intervalo seja menor do que o tempo necessário para o comando terminar, ou então isso pode interferir em algo em seu script.
Também é importante notar que usando isso, o tempo irá variar, dependendo de quanto tempo o comando que você está executando leva para ser concluído. Por exemplo, se você deseja executar um comando a cada 5 segundos, mas esse comando leva 3 segundos para ser concluído, isso fará com que o comando seja executado a cada 8 segundos, em vez de a cada 5 segundos.
Uma solução para evitar essa flutuação de tempo e executar o comando a cada X segundos, independentemente de quanto tempo leva para ser concluído (desde que o comando não leve mais para ser concluído do que o tempo de suspensão), é usar o seguinte:
while true; do
Aqui, substitua comando pelo comando que deseja executar e ambas as instâncias de X com o número de segundos após o qual o comando deve ser repetido.
Atenção: Esta solução não é perfeita. Leia a explicação e a alternativa para isso nas edições marcadas mais adiante neste artigo.
Exemplo. O seguinte one-liner repete o comando sleep 3 (não poderia pensar em um exemplo melhor agora de um comando que leva alguns segundos para ser concluído e não é destrutivo de forma alguma caso o usuário não o interrompa - Estou digitando às 5h) a cada 5 segundos:
while true; do sleep 3; sleep $((5 - $(date +%s) % 5)); done
Usando isso, embora o comando (sleep 3 neste caso, pode ser qualquer comando que você deseja) leve 3 segundos para ser concluído, o intervalo entre as execuções é de 5 segundos.
Para testar isso, você pode adicionar um echo $(date) no início, como este:
while true; do echo $(date); sleep 3; sleep $((5 - $(date +%s) % 5)); done
Você perceberá que a data impressa no terminal está em incrementos de 5 segundos, como este:
Thu 10 Dec 05:48:00 2020
Thu 10 Dec 05:48:05 2020
Thu 10 Dec 05:48:10 2020
Thu 10 Dec 05:48:15 2020
Atenção: Esta solução não é perfeita. Entre a primeira e a segunda execução, o intervalo de tempo pode ser menor do que o especificado. No entanto, as execuções subsequentes usam o intervalo de tempo correto. Se você conhece a melhor maneira de fazer isso, deixe um comentário abaixo.
Dica: Uma solução (via stackexchange) que evita flutuação no tempo e não tem o problema que mencionei acima (portanto, nenhum intervalo de tempo diferente entre a primeira e a segunda execução), mas que não faz uso do comando sleep, é o seguinte comando de uma linha:**
while true; do currentTime=$(date +%s); elapsedTime=$((currentTime - lastTime)); if [ $elapsedTime -ge
Substitua X com o intervalo de tempo entre as execuções (em segundos) e comando com o comando que deseja repetir a cada X segundos.
Uma pequena explicação é necessária aqui. Este loop while armazena o tempo Unix atual como currentTime e, em seguida, subtrai o último tempo (lastTime) do tempo atual, armazenando como elapsedTime. Em seguida, ele verifica se o tempo decorrido é maior ou igual a X e se for, ele executa command (então o comando é repetido a cada X segundos). E, finalmente, ele define o último tempo para ser igual ao tempo atual, portanto, da próxima vez que for executado, ele pode subtrair lastTime do currentTime, o que dá o valor elapsedTime. Espero que isso faça sentido para você como faz na minha cabeça 😁️.
Exemplo. A seguinte linha repete os comandos echo $(date) e sleep 2 (usei sleep 2, portanto, o comando leva alguns segundos para ser verificado, se não for concluído).
while true; do currentTime=$(date +%s); elapsedTime=$((currentTime - lastTime)); if [ $elapsedTime -ge 5 ]; then echo $(date); sleep 2; lastTime=$currentTime; i=0; fi; done
Você também pode gostar de: Como excluir arquivos mais antigos ou mais recentes do que N dias usando find (com exemplos extras)
Esse post foi traduzido do site LinuxUprising.com pela rtland.team.
Confira a versão original desse post em inglês:
How To Repeat A Command Every X Seconds On Linux