Bash: спать до определенного времени / даты - PullRequest
72 голосов
/ 14 марта 2009

Я хочу, чтобы мой bash-скрипт спал до определенного времени. Итак, мне нужна команда типа «сон», которая не занимает ни одного интервала, а времени окончания и спит до тех пор.

Демон "at" не является решением, так как мне нужно заблокировать работающий скрипт до определенной даты / времени.

Есть ли такая команда?

Ответы [ 16 ]

1 голос
/ 19 июля 2016
 function sleepuntil() {
  local target_time="$1"
  today=$(date +"%m/%d/%Y")
  current_epoch=$(date +%s)
  target_epoch=$(date -d "$today $target_time" +%s)
  sleep_seconds=$(( $target_epoch - $current_epoch ))

  sleep $sleep_seconds
}

target_time="11:59"; sleepuntil $target_time
1 голос
/ 14 марта 2009

Возможно, вы могли бы использовать 'at' для отправки сигнала в ваш скрипт, который сидел в ожидании этого сигнала.

1 голос
/ 14 марта 2009

Вы можете рассчитать количество секунд между текущим моментом и временем пробуждения и использовать существующую команду 'sleep'.

0 голосов
/ 30 октября 2017

Я действительно написал https://tamentis.com/projects/sleepuntil/ для этой конкретной цели. Это немного чрезмерно, большая часть кода поступает из BSD 'at', поэтому он достаточно совместим со стандартами:

$ sleepuntil noon && sendmail something
0 голосов
/ 11 сентября 2015

На 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 минут, тогда у нас все равно будет время, чтобы наверстать упущенное, без чего-либо переходящего в следующий час).

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

0 голосов
/ 11 июня 2013

Вот что я написал для синхронизации нескольких тестовых клиентов:

#!/usr/bin/python
import time
import sys

now = time.time()
mod = float(sys.argv[1])
until = now - now % mod + mod
print "sleeping until", until

while True:
    delta = until - time.time()
    if delta <= 0:
        print "done sleeping ", time.time()
        break
    time.sleep(delta / 2)

Этот сценарий спит до следующего "округленного" или "острого" времени.

Простой вариант использования - запустить ./sleep.py 10; ./test_client1.py в одном терминале и ./sleep.py 10; ./test_client2.py в другом.

...