Durma até a próxima ocorrência de horário específico

Durma até a próxima ocorrência de horário específico

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 atcomando ou cronjob não é uma opção porque não devo sair do script em que estou atualmente.

O caso específico de que estou falando é um script rodando na tela. É muito importante que eu não interrompa a execução do script pelo próprio script, pois há muitas variáveis ​​importantes armazenadas que são necessárias em algum ponto do script. O script nem sempre deve ser executado regularmente. Ele só precisa ser executado em um horário específico.

Seria muito benéfico se o script tivesse que criar algum arquivo ou qualquer outra tarefa, como cronjobs ou outras telas. Esta é 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!

Responder1

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 calcula a diferença entre o tempo determinado e o tempo atual em segundos. Se o número for negativo temos que somar os segundos de um dia inteiro (86400 para ser exato) para obter os segundos que temos para dormir e se o número for positivo podemos simplesmente usá-lo.

Responder2

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ê quiser que isso continue às 4h e às 16h, use isto:

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

Responder3

SobreOpenBSD, o seguinte poderia ser usado para compactar um intervalo de */55 minutoscrontab(5)trabalho em um 00de hora em hora (para garantir que menos e-mails sejam gerados, tudo isso enquanto executa 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 odate(1)também quebraria osleep(1)intencionalmente na iteração final, já que 60minutos não é um tempo válido (a menos que seja!), portanto, não teremos que esperar nenhum tempo extra antes de receber nosso relatório por e-mail.

Observe também que, se uma das iterações levar mais de 5 minutos atribuídos a ela, ela sleeptambém falharia graciosamente por não dormir (devido ao que é um número negativo interpretado como uma opção de linha de comando, em vez de passar para a próxima hora ou mesmo a eternidade), garantindo assim que seu trabalho ainda possa ser concluído dentro da hora prevista (por exemplo, se apenas uma das iterações levar um pouco mais de 5 minutos, ainda teremos tempo para atualizá-lo, sem qualquer coisa envolvendo até a próxima hora).

Oprintf(1)é necessário porque dateespera exatamente dois dígitos para a especificação dos minutos.

informação relacionada