Dormir hasta la próxima aparición de un tiempo específico.

Dormir hasta la próxima aparición de un tiempo específico.

Necesito una serie de comandos o un solo comando que duerma hasta que ocurra la próxima vez que ocurra una hora específica como "4:00".

¿Como podría hacerlo?

El atcomando o un cronjob no es una opción porque no debo salir del script en el que estoy actualmente.

El caso específico del que estoy hablando es un script que se ejecuta en la pantalla. Es muy importante que no detenga la ejecución del script mediante el script mismo porque se almacenan muchas variables importantes que son necesarias en algún punto del script. No siempre se supone que el script se ejecute de forma regular. Sólo es necesario ejecutarlo en un momento específico.

Sería muy beneficioso si el script tuviera que crear archivos o cualquier otra tarea, como cronjobs u otras pantallas. Esto es simplemente una cuestión de diseño.

Se me acaba de ocurrir una idea genial:

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

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

¿Tienes alguna idea mejor?

¡Se agregará más información si se solicita!

Respuesta1

La sugerencia de Terdon funcionaría, pero supongo que la mía es más eficiente.

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

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

Esto calcula la diferencia entre la hora dada y la hora actual en segundos. Si el número es negativo tenemos que sumar los segundos de un día entero (86400 para ser exactos) para obtener los segundos que tenemos para dormir y si el número es positivo simplemente podemos usarlo.

Respuesta2

Suponiendo que sea un script de shell, esto debería funcionar:

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

Eso es para horarios de 24 horas. Si desea que esto continúe a las 4:00 a. m. y a las 4:00 p. m., utilice esto en su lugar:

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

Respuesta3

EnOpenBSD, lo siguiente podría usarse para compactar un */5tiempo de 5 minutoscrontab(5)trabajo en 00uno por horas (para asegurarse de que se generen menos correos electrónicos, todo mientras se realiza la misma tarea en intervalos exactos):

#!/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

Tenga en cuenta que eldate(1)también rompería elsleep(1)por diseño en la iteración final, ya que 60los minutos no son un tiempo válido (¡a menos que lo sea!), por lo que no tendremos que esperar más tiempo antes de recibir nuestro informe por correo electrónico.

También tenga en cuenta que si una de las iteraciones toma más de 5 minutos asignados, sleeptambién fallaría por diseño al no dormir en absoluto (debido a que es un número negativo interpretado como una opción de línea de comando, en lugar de ajustarse a la próxima hora o incluso la eternidad), asegurándonos así de que su trabajo aún pueda completarse dentro de la hora asignada (por ejemplo, si solo una de las iteraciones toma un poco más de 5 minutos, entonces aún tendríamos tiempo para ponernos al día, sin cualquier cosa que se acerque a la próxima hora).

Elprintf(1)es necesario porque dateespera exactamente dos dígitos para la especificación de minutos.

información relacionada