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

11

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

¿Como podría hacerlo?

El atcomando o un cronjob no es una opción porque no debo dejar el 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 por el script en sí porque hay muchas variables importantes que se necesitan en algún punto del script. No siempre se supone que el script se ejecute de manera regular. Solo necesita ejecutarse en un momento específico.

Sería muy benéfico si el script tuviera que crear algún archivo o cualquier otra tarea como cronjobs u otras pantallas. Esto es simplemente una cuestión de diseño.

Acabo de tener una idea increíble:

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!

BrainStone
fuente
¿Podría aclarar un poco su pregunta? ¿Qué quieres decir cuando dices: "No debo dejar el guión en el que me encuentro actualmente"
sebelk
¿Qué tal si su script comprueba la existencia de un archivo de "activación" y duerme por un período de tiempo antes de verificar nuevamente? Luego puede usar cron para crear el archivo, aprovechando la confiabilidad de cron, pero también puede tener su script de larga duración. Simplemente haga que el script elimine el archivo "despertar" cuando deja de dormir.
kurtm
Tenga en cuenta que en un Mac se debe reemplazar date -dcon date -jy reemplazar 4:00con 0400.
pjvandehaar

Respuestas:

17

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 es calcular la diferencia entre el tiempo dado y el tiempo actual en segundos. Si el número es negativo, tenemos que agregar los segundos durante todo un día (86400 para ser exactos) para obtener los segundos que tenemos que dormir y si el número es positivo, podemos usarlo.

BrainStone
fuente
¿Qué sucede si el reloj del sistema se mueve hacia adelante / hacia atrás (por ejemplo: ntp)?
WhyNotHugo
10

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

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

Eso es por 24 horas veces. Si desea que esto continúe tanto a las 4:00 a.m. como a las 4:00 p.m., use esto en su lugar:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done
terdon
fuente
Esta podría ser una opción. Acabo de tener una idea. Regresaré en unos minutos.
BrainStone
0

En OpenBSD , lo siguiente podría usarse para compactar un trabajo de */55 minutos crontab(5)en 00uno por hora (para asegurarse de que se generen menos correos electrónicos, todo mientras se realiza la misma tarea a 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 date(1)también rompería el sleep(1)diseño en la iteración final, ya que los 60minutos no son un tiempo válido (a menos que lo sea), por lo que no tendremos que esperar ningún tiempo adicional antes de recibir nuestro informe por correo electrónico.

También tenga en cuenta que si una de las iteraciones demora más de 5 minutos, sleeptambién fallaría gentilmente por diseño al no dormir (debido a lo que es un número negativo interpretado como una opción de línea de comandos, en lugar de ajustarse a la siguiente hora o incluso la eternidad), asegurándose de que su trabajo aún pueda completarse dentro de la hora asignada (por ejemplo, si solo una de las iteraciones demora un poco más de 5 minutos, aún tendríamos el tiempo para ponernos al día, sin cualquier cosa que envuelva hasta la próxima hora).

Se printf(1)necesita porque dateespera exactamente dos dígitos para la especificación de minutos.

cnst
fuente