Suspender até a próxima ocorrência do tempo específico

9

Eu preciso de uma série de comandos ou de um único comando que durma até que ocorra a próxima ocorrência de um horário específico como "4:00".

Como eu faria isso?

O comando at ou um cronjob não é uma opção porque não devo deixar o script no qual estou atualmente.

O caso específico de que estou falando é um script sendo executado na tela. É muito importante que eu não pare a execução do script pelo próprio script, pois existem muitas variáveis importantes que são necessárias em algum ponto do script. O script nem sempre deve ser executado em um assunto regular. Só precisa ser executado em um horário específico.

Seria muito benéfico se o script tivesse que criar arquivos ou outras tarefas, como cronjobs ou outras telas. Isto é simplesmente uma questão de design.

Acabei de ter uma ideia incrível:

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Você tem alguma ideia melhor?

Mais informações serão adicionadas, se solicitado!

    
por BrainStone 10.10.2013 / 23:17

3 respostas

15

A sugestão de Terdon funcionaria, mas acho que a minha é mais eficiente.

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

Isso é calcular a diferença entre o tempo determinado e o tempo atual em segundos. Se o número for negativo, temos que adicionar os segundos para um dia inteiro (86400 para ser exato) para obter os segundos que temos para dormir e se o número for positivo, podemos usá-lo.

    
por 11.10.2013 / 01:46
9

Supondo que seja um script de shell, isso deve funcionar:

while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done

Isso é por 24 horas. Se você deseja que isso continue às 4:00 e às 16:00, use:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done
    
por 10.10.2013 / 23:25
0

No OpenBSD , o seguinte pode ser usado para compactar um */5 5-minutos crontab(5) trabalho em um 00 por hora (para ter certeza de que menos e-mails serão gerados, tudo durante a mesma tarefa em intervalos exatos):

#!/bin/sh -x
for k in $(jot 12 00 55)
  do
  echo $(date) doing stuff
  sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done

Observe que o date(1) também quebraria o sleep(1) por design na iteração final, pois 60 minutos não é um tempo válido (a menos que seja!), portanto não teremos que esperar nenhum tempo extra antes para obter nosso relatório de e-mail.

Observe também que, se uma das iterações levar mais de 5 minutos, a sleep também falhará de propósito se não for totalmente adormecida (devido a um número negativo interpretado como uma opção de linha de comando) , em vez de passar para a próxima hora ou até mesmo a eternidade), garantindo que seu trabalho ainda possa ser concluído dentro de uma hora alocada (por exemplo, se apenas uma das iterações demorar um pouco mais de 5 minutos, ainda teríamos tempo para recuperar o tempo perdido, sem nada para a próxima hora).

O printf(1) é necessário porque date espera exatamente dois dígitos para a especificação do minuto.

    
por 11.09.2015 / 11:29