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 at
comando 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 */5
tiempo de 5 minutoscrontab(5)
trabajo en 00
uno 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 60
los 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, sleep
tambié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 date
espera exactamente dos dígitos para la especificación de minutos.