Unix: спать до указанного времени

12

Существует ли (полу) стандартная команда Unix, которая будет спать до времени, указанного в командной строке? Другими словами, я ищу что-то похожее, sleepчто потребовало бы времени пробуждения, а не продолжительности.

Например: sleeptill 05:00:00

Я могу что-то написать, но не буду изобретать велосипед, если что-то уже есть.

Бонусный вопрос: было бы здорово, если бы он занимал часовой пояс (как в sleeptill 05:00:00 America/New_York).

edit Из-за характера того, что я делаю, я ищу решение «спать до T», а не «выполнить команду при T».

редактировать Во избежании сомнений, если я запускаю команду в 18:00 и сказать ему , чтобы проснуться в 17:00, я ожидал , чтобы спать в течение 23 часов (или, в некоторых случаях угловых , имеющих отношение к летнему времени, на 22 или 24 часа.)

NPE
источник
Вы могли бы использовать cron, я думаю.
Бобби
Спасибо, но для предполагаемого использования это действительно должно быть sleepпохоже.
NPE

Ответы:

18

Если вы работаете в Unix с командой приличной даты и используете bash, вы можете использовать формат% s для расчета времени.

sleep $(( $(date -j 1700 +%s) - $(date +%s) ))

(1700 - это 5 вечера, а -j говорит, что не нужно устанавливать дату)

w00t
источник
(+1) за предложение. Если я выполню команду в 18:00 и скажу, что она проснется в 17:00, я ожидаю, что она будет спать 23 часа (или, в некоторых случаях, связанных с переходом на летнее время, в течение 22 или 24 часов). Здесь, к сожалению, это предложение рушится. [Мне также пришлось изменить -jего, -dчтобы он работал на моих системах Linux.]
NPE
7
@aix: В Linux (и других системах с датой GNU) вы можете использовать сложные спецификации даты, такие как date -d 'tomorrow 17:00'.
Жиль "ТАК - перестань быть злым"
3
@NPE, кстати, можно компенсировать это с помощью напоминания-разделения: echo $(( ($(date -d "3:00" +%s) - $(date +%s) + (60*60*24)) % (60*60*24) ))(могут быть только некоторые проблемы с изменениями DST)
hvr
13

Как насчет этого (объединение идей w00t и Gille в функцию)?

function sleep_until {
  seconds=$(( $(date -d "$*" +%s) - $(date +%s) )) # Use $* to eliminate need for quotes
  echo "Sleeping for $seconds seconds"
  sleep $seconds
}

Применение:

sleep_until 8:24
Sleeping for 35 seconds

sleep_until '23:00'
Sleeping for 52489 seconds

sleep_until 'tomorrow 1:00'
Sleeping for 59682 seconds
Тайлер Рик
источник
9

Проверьте / Linux Unix atкоманды . Используя пример 5 утра:

at 05:00 some_command

Он также поддерживает часовые пояса:

Имя часового пояса GMT, UCT или ZULU (без учета регистра) может следовать, чтобы указать, что время указано в Всемирном координированном времени. Другие часовые пояса могут быть указаны с помощью переменной окружения TZ.

Джереми Л
источник
(+1) за предложение. К сожалению, это не вписывается в мой рабочий процесс. У меня есть сценарий, который выполняет кучу вещей в последовательности, и я хочу, чтобы определенные шаги не выполнялись до определенного времени. Это, конечно, может быть преобразовано во что-то, что использует cronили at, но это будет больно управлять. Вот почему я ищу что-то подобное sleep. На данный момент я написал свой собственный.
NPE
Ах, ты хочешь график блокировки. Почему бы не иметь файл состояния, отслеживающий каждый шаг процесса?
Джереми Л
Мог бы, но это звучит несколько сложнее, чем я думаю. Шаги представляют собой разрозненные команды, а сценарий оболочки - это то, что управляет рабочим процессом. Возможность «спать до 5 вечера» в сценарии - это все, что мне действительно нужно.
NPE
В этом случае ответ w00t может быть именно тем, что вы ищете.
Джереми Л
Да, это определенно в правильном духе. К сожалению, он ломается в некоторых важных (для меня) случаях и не делает часовых поясов.
NPE