Мне нужна серия команд или одна команда, которая будет действовать до следующего наступления определенного времени, например, «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
У вас есть идеи получше?
По запросу будет добавлена дополнительная информация!
решение1
Предложение Тердона сработало бы, но я полагаю, что мое более эффективно.
difference=$(($(date -d "4:00" +%s) - $(date +%s)))
if [ $difference -lt 0 ]
then
sleep $((86400 + difference))
else
sleep $difference
fi
Это вычисление разницы между заданным временем и текущим временем в секундах. Если число отрицательное, то нам нужно прибавить секунды за весь день (86400, если быть точным), чтобы получить секунды, которые у нас есть на сон, а если число положительное, то мы можем просто использовать его.
решение2
Если предположить, что это скрипт оболочки, то это должно работать:
while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done
Это для 24-часового времени. Если вы хотите, чтобы это продолжалось и в 4:00 утра, и в 4:00 вечера, используйте это:
while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done
решение3
НаOpenBSD, следующее можно использовать для сжатия */5
5-минутного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 минут, то у нас все еще будет время наверстать упущенное, без переноса на следующий час).
Theprintf(1)
необходимо, поскольку date
для указания минут требуется ровно две цифры.