Сон до следующего появления определенного времени


11

Мне нужна серия команд или одна команда, которая спит, пока не произойдет следующее вхождение определенного времени, например «4:00».

Как бы я это сделал?

Команда atили cronjob не вариант, потому что я не должен оставлять сценарий, в котором я сейчас нахожусь.

Конкретный случай, о котором я говорю, - это скрипт, работающий на экране. Очень важно, чтобы я не останавливал выполнение сценария самим сценарием, поскольку в нем хранится много важных переменных, которые необходимы в какой-то момент сценария. Сценарий не всегда должен выполняться в обычном режиме. Это просто нужно выполнить в определенное время.

Было бы очень полезно, если бы сценарию пришлось создавать какие-либо файлы или любые другие задачи, такие как cronjobs или другие экраны. Это просто вопрос дизайна.

У меня просто была отличная идея:

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

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

У вас есть идеи получше?

Дополнительная информация будет добавлена ​​по запросу!


Пожалуйста, не могли бы вы уточнить ваш вопрос? Что вы имеете в виду, когда говорите: «Я не должен оставлять сценарий, в котором я сейчас нахожусь»
Себелк

Как насчет того, чтобы ваш сценарий проверил наличие файла «проснуться» и поспать какое-то время, прежде чем проверять снова? Затем вы можете использовать cron для создания файла, используя надежность cron, но у вас также может быть свой долгоживущий скрипт. Просто сделайте так, чтобы скрипт удалил файл "пробуждения", когда он перестает спать.
Куртм

Обратите внимание, что на Mac вы должны заменить date -dна date -jи заменить 4:00на 0400.
pjvandehaar

Ответы:


17

Предложение Тердона сработало бы, но, думаю, мое более эффективно.

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

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

Это вычисление разницы между данным временем и текущим временем в секундах. Если число отрицательное, мы должны добавить секунды за целый день (если быть точным, 86400), чтобы получить секунды, которые мы должны спать, и если число положительное, мы можем просто использовать его.


Что произойдет, если системные часы будут двигаться вперед / назад (например, ntp).
WhyNotHugo

10

Предполагая, что это сценарий оболочки, это должно работать:

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

Это в течение 24 часов. Если вы хотите, чтобы это продолжалось в 4:00 AM и 4:00 PM, используйте вместо этого:

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

Это может быть вариантом. У меня только что была идея. Я вернусь через несколько минут.
BrainStone

0

В OpenBSD следующее можно использовать для объединения */55-минутной crontab(5)работы в 00почасовую (чтобы обеспечить генерацию меньшего количества электронных писем при выполнении одной и той же задачи с точными интервалами):

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

Обратите внимание, что date(1)это также нарушило бы sleep(1)дизайн на последней итерации, поскольку 60минуты не являются допустимым временем (если это не так!), Поэтому нам не придется ждать дополнительного времени до получения нашего отчета по электронной почте.

Также обратите внимание, что если одна из итераций займет более 5 минут, она также sleepбудет любезно завершена с ошибкой, вообще не спя (из-за того, что отрицательное число интерпретируется как параметр командной строки, вместо того, чтобы переходить к следующий час или даже вечность), таким образом, убедившись, что ваша работа все еще может быть завершена в течение выделенного часа (например, если только одна из итераций занимает чуть более 5 минут, то у нас все еще будет время, чтобы наверстать упущенное, без что-нибудь на следующий час).

printf(1)Необходимо , потому что dateпредпологает ровно две цифры для минут спецификации.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.