Спите до определенного времени / даты

89

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

«At» -daemon не является решением, так как мне нужно заблокировать работающий скрипт до определенной даты / времени.

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

Theomega
источник
1
Обратите внимание, что решение, которое просто использует длительный спящий режим, которому предшествуют вычисления, может спать слишком долго, может быть, слишком долго, особенно если у вас есть машина, которая может переходить в спящий режим. Команда posix sleep не обещает, что не спит слишком долго. Решение @Camusensei очень хорошо решает эту проблему.
GregD

Ответы:

98

Как упомянул программист-преступник, я думаю, что решение - просто спать на нужное количество секунд.

Чтобы сделать это в bash, сделайте следующее:

current_epoch=$(date +%s)
target_epoch=$(date -d '01/01/2010 12:00' +%s)

sleep_seconds=$(( $target_epoch - $current_epoch ))

sleep $sleep_seconds

Чтобы повысить точность до наносекунд (а точнее, до миллисекунд), используйте, например, следующий синтаксис:

current_epoch=$(date +%s.%N)
target_epoch=$(date -d "20:25:00.12345" +%s.%N)

sleep_seconds=$(echo "$target_epoch - $current_epoch"|bc)

sleep $sleep_seconds

Обратите внимание, что macOS / OS X не поддерживает точность ниже секунд, вместо этого вам необходимо использовать coreutilsfrom brewсм. Эти инструкции

SpoonMeiser
источник
8
Спасибо за это, я написал небольшой shell-скрипт для получения команды "sleepuntil".
theomega
1
@enigmaticPhysicist: есть аналогичный вызов команды "at", который запускается асинхронно.
voidlogic
6
Если вы хотите остановиться завтра в 3 часа ночи, вы можете использовать target_epoch=$(date -d 'tomorrow 03:00' +%s)вместо этого.
Yajo
Вы можете сделать то же самое, используя одну вилку dateвместо двух! Смотрите первую часть моего ответа
Ф. Хаури
1
Обратите внимание, что это решение потенциально может спать слишком долго, а если ваша машина немного перейдет в спящий режим, это может быть слишком долго.
GregD
23

Поскольку этот вопрос был задан 4 года назад, первая часть касается старых версий bash:

Последнее изменение: среда, 22 апреля 2020 г., что-то между 10:30 и 10:55 (важно для чтения образцов)

Общий метод (Избегайте бесполезных вилок!)

(Примечание: этот метод используется date -fне в POSIX и не работает под MacOS! Если под Mac, перейдите к моему чистомуфункция )

Чтобы уменьшить forks, вместо того, чтобы запускать dateдва раза, я предпочитаю использовать это:

Простой стартовый образец

sleep $(($(date -f - +%s- <<< $'tomorrow 21:30\nnow')0))

где tomorrow 21:30может быть заменен любой датой и форматом, распознаваемым dateв будущем.

С высокой точностью (наносекунд)

Почти то же самое:

sleep $(bc <<<s$(date -f - +'t=%s.%N;' <<<$'07:00 tomorrow\nnow')'st-t')

Достигнув следующего раза

Для достижения следующегоHH:MM значения сегодня, если возможно, завтра, если слишком поздно:

sleep $((($(date -f - +%s- <<<$'21:30 tomorrow\nnow')0)%86400))

Это работает под , и другие современные оболочки, но вы должны использовать:

sleep $(( ( $(printf 'tomorrow 21:30\nnow\n' | date -f - +%s-)0 )%86400 ))

под более легкими снарядами, такими как или .

Чистый Кстати, вилки нет !!

Проверено под MacOS!

Я написал одну две маленькие функции: sleepUntilиsleepUntilHires

 Syntax:
 sleepUntil [-q] <HH[:MM[:SS]]> [more days]
     -q Quiet: don't print sleep computed argument
     HH          Hours (minimal required argument)
     MM          Minutes (00 if not set)
     SS          Seconds (00 if not set)
     more days   multiplied by 86400 (0 by default)

Поскольку новые версии bash предлагают printfвозможность получения даты, для этого нового способа засыпать до ЧЧ: ММ без использования dateили какой-либо другой вилки, я немного построилфункция. Вот:

sleepUntil() { # args [-q] <HH[:MM[:SS]]> [more days]
    local slp tzoff now quiet=false
    [ "$1" = "-q" ] && shift && quiet=true
    local -a hms=(${1//:/ })
    printf -v now '%(%s)T' -1
    printf -v tzoff '%(%z)T\n' $now
    tzoff=$((0${tzoff:0:1}(3600*${tzoff:1:2}+60*${tzoff:3:2})))
    slp=$((
       ( 86400+(now-now%86400) + 10#$hms*3600 + 10#${hms[1]}*60 + 
         ${hms[2]}-tzoff-now ) %86400 + ${2:-0}*86400
    ))
    $quiet || printf 'sleep %ss, -> %(%c)T\n' $slp $((now+slp))
    sleep $slp
}

Затем:

sleepUntil 10:37 ; date +"Now, it is: %T"
sleep 49s, -> Wed Apr 22 10:37:00 2020
Now, it is: 10:37:00

sleepUntil -q 10:37:44 ; date +"Now, it is: %T"
Now, it is: 10:37:44

sleepUntil 10:50 1 ; date +"Now, it is: %T"
sleep 86675s, -> Thu Apr 23 10:50:00 2020
^C

Если цель раньше, это будет спать до завтра:

sleepUntil 10:30 ; date +"Now, it is: %T"
sleep 85417s, -> Thu Apr 23 10:30:00 2020
^C

sleepUntil 10:30 1 ; date +"Now, it is: %T"
sleep 171825s, -> Fri Apr 24 10:30:00 2020
^C

Время HiRes с под GNU / Linux

Недавние , с версии 5.0 добавлена ​​новая $EPOCHREALTIMEпеременная с микросекундами. От этого есть sleepUntilHiresфункция.

sleepUntilHires () { # args [-q] <HH[:MM[:SS]]> [more days]
    local slp tzoff now quiet=false musec musleep;
    [ "$1" = "-q" ] && shift && quiet=true;
    local -a hms=(${1//:/ });
    printf -v now '%(%s)T' -1;
    IFS=. read now musec <<< $EPOCHREALTIME;
    musleep=$[2000000-10#$musec];
    printf -v tzoff '%(%z)T\n' $now;
    tzoff=$((0${tzoff:0:1}(3600*${tzoff:1:2}+60*${tzoff:3:2})));
    slp=$(((( 86400 + ( now - now%86400 ) +
            10#$hms*3600+10#${hms[1]}*60+10#${hms[2]} -
            tzoff - now - 1
            ) % 86400 ) + ${2:-0} * 86400
          )).${musleep:1};
    $quiet || printf 'sleep %ss, -> %(%c)T\n' $slp $((now+${slp%.*}+1));
    read -t $slp foo
}

Обратите внимание: это read -tвстроенное использование вместо sleep. К сожалению, это не сработает при работе в фоновом режиме без реального TTY. Не стесняйтесь заменить read -tна, sleepесли вы планируете запускать это в фоновых сценариях ... (Но для фонового процесса рассмотрите возможность использования cronи / или atвместо всего этого)

Пропустите следующий абзац, чтобы узнать о тестах и ​​предупреждениях $ËPOCHSECONDS!

Последнее ядро ​​не используется /proc/timer_listпользователем !!

В недавнем ядре Linux вы найдете файл переменных с именем `/ proc / timer_list`, в котором вы можете прочитать переменную` offset` и `now` за ** наносекунды **. Таким образом, мы можем вычислить время сна, чтобы достичь * самого верхнего * желаемого времени.

(Я написал это для генерации и отслеживания конкретных событий в очень больших файлах журнала, содержащих тысячу строк за одну секунду).

mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
    [[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_SKIP=$_i
    [[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
    TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
     break
done
unset _i _timer_list
readonly TIMER_LIST_OFFSET TIMER_LIST_SKIP

sleepUntilHires() {
    local slp tzoff now quiet=false nsnow nsslp
    [ "$1" = "-q" ] && shift && quiet=true
    local hms=(${1//:/ })
    mapfile -n 1 -s $TIMER_LIST_SKIP nsnow </proc/timer_list
    printf -v now '%(%s)T' -1
    printf -v tzoff '%(%z)T\n' $now
    nsnow=$((${nsnow//[a-z ]}+TIMER_LIST_OFFSET))
    nsslp=$((2000000000-10#${nsnow:${#nsnow}-9}))
    tzoff=$((0${tzoff:0:1}(3600*${tzoff:1:2}+60*${tzoff:3:2})))
    slp=$(( ( 86400 + ( now - now%86400 ) +
            10#$hms*3600+10#${hms[1]}*60+${hms[2]} -
            tzoff - now - 1
        ) % 86400)).${nsslp:1}
    $quiet || printf 'sleep %ss, -> %(%c)T\n' $slp $((now+${slp%.*}+1))
    sleep $slp
}

После определения двух переменных, доступных только для чтения , TIMER_LIST_OFFSETи TIMER_LIST_SKIPфункция очень быстро получит доступ к файлу переменных /proc/timer_listдля вычисления времени сна:

Маленькая тестовая функция

tstSleepUntilHires () { 
    local now next last
    printf -v next "%(%H:%M:%S)T" $((${EPOCHREALTIME%.*}+1))
    sleepUntilHires $next
    date -f - +%F-%T.%N < <(echo now;sleep .92;echo now)
    printf -v next "%(%H:%M:%S)T" $((${EPOCHREALTIME%.*}+1))
    sleepUntilHires $next
    date +%F-%T.%N
}

Может отображать что-то вроде:

sleep 0.244040s, -> Wed Apr 22 10:34:39 2020
2020-04-22-10:34:39.001685312
2020-04-22-10:34:39.922291769
sleep 0.077012s, -> Wed Apr 22 10:34:40 2020
2020-04-22-10:34:40.004264869
  • В начале следующей секунды
  • время печати, тогда
  • подождите 0,92 секунды, затем
  • время печати, тогда
  • вычислить 0,07 секунды до следующей секунды
  • спать 0,07 секунды, затем
  • время печати.

Не смешивайте $EPOCHSECONDи $EPOCHREALTIME!

Прочтите мое предупреждение о разнице между $EPOCHSECONDи$EPOCHREALTIME

Эта функция используется, $EPOCHREALTIMEпоэтому не используйте ее $EPOCHSECONDдля установки следующей секунды :

Пример проблемы: попытка напечатать время с округлением на 2 секунды:

for i in 1 2;do
    printf -v nextH "%(%T)T" $(((EPOCHSECONDS/2)*2+2))
    sleepUntilHires $nextH
    IFS=. read now musec <<<$EPOCHREALTIME
    printf "%(%c)T.%s\n" $now $musec
done

Может производить:

sleep 0.587936s, -> Wed Apr 22 10:51:26 2020
Wed Apr 22 10:51:26 2020.000630
sleep 86399.998797s, -> Thu Apr 23 10:51:26 2020
^C
Ф. Хаури
источник
1
Вот это да! Вычисление наносекунд под bash !
Ф. Хаури,
Вычисление микросекунд под родным bash v5 + !!
Ф. Хаури,
21

Используйте sleep, но вычислите время, используя date. Вы захотите использовать date -dдля этого. Например, допустим, вы хотите подождать до следующей недели:

expr `date -d "next week" +%s` - `date -d "now" +%s`

Просто замените «на следующей неделе» на дату, которую вы хотите дождаться, затем присвойте этому выражению значение и засыпайте столько секунд:

startTime=$(date +%s)
endTime=$(date -d "next week" +%s)
timeToWait=$(($endTime- $startTime))
sleep $timeToWait

Все сделано!

Джон Феминелла
источник
Стоит подробнее рассказать о том, как вы назначаете значение переменной, поскольку timeToWait = expr ... не будет работать напрямую, и вы не можете использовать обратные кавычки, потому что они не будут вкладываться, поэтому вам придется использовать $ () или временные переменные.
SpoonMeiser,
Хорошее предложение; Я изменю свой, чтобы прояснить это, чтобы люди не поняли неверное представление.
Джон Феминелла
На данный момент Note не -dявляется расширением POSIX. В FreeBSD он пытается установить значение ядра для перехода на летнее время.
Дэйв К.
9

Вот решение, которое выполняет свою работу И информирует пользователя о том, сколько времени осталось. Я использую его почти каждый день для запуска скриптов ночью (используя cygwin, так как я не мог cronработать с Windows)

Характеристики

  • С точностью до секунды
  • Обнаруживает изменения системного времени и адаптируется
  • Интеллектуальный вывод, показывающий, сколько времени осталось
  • 24-часовой формат ввода
  • возвращает true, чтобы иметь возможность связываться с &&

Пробный запуск

$ til 13:00 && date
1 hour and 18 minutes and 26 seconds left...
1 hour and 18 minutes left...
1 hour and 17 minutes left...
1 hour and 16 minutes left...
1 hour and 15 minutes left...
1 hour and 14 minutes left...
1 hour and 10 minutes left...
1 hour and  5 minutes left...
1 hour and  0 minutes left...
55 minutes left...
50 minutes left...
45 minutes left...
40 minutes left...
35 minutes left...
30 minutes left...
25 minutes left...
20 minutes left...
15 minutes left...
10 minutes left...
 5 minutes left...
 4 minutes left...
 3 minutes left...
 2 minutes left...
 1 minute left...
Mon, May 18, 2015  1:00:00 PM

(Дата в конце не является частью функции, а связана с && date)

Код

til(){
  local hour mins target now left initial sleft correction m sec h hm hs ms ss showSeconds toSleep
  showSeconds=true
  [[ $1 =~ ([0-9][0-9]):([0-9][0-9]) ]] || { echo >&2 "USAGE: til HH:MM"; return 1; }
  hour=${BASH_REMATCH[1]} mins=${BASH_REMATCH[2]}
  target=$(date +%s -d "$hour:$mins") || return 1
  now=$(date +%s)
  (( target > now )) || target=$(date +%s -d "tomorrow $hour:$mins")
  left=$((target - now))
  initial=$left
  while (( left > 0 )); do
    if (( initial - left < 300 )) || (( left < 300 )) || [[ ${left: -2} == 00 ]]; then
      # We enter this condition:
      # - once every 5 minutes
      # - every minute for 5 minutes after the start
      # - every minute for 5 minutes before the end
      # Here, we will print how much time is left, and re-synchronize the clock

      hs= ms= ss=
      m=$((left/60)) sec=$((left%60)) # minutes and seconds left
      h=$((m/60)) hm=$((m%60)) # hours and minutes left

      # Re-synchronise
      now=$(date +%s) sleft=$((target - now)) # recalculate time left, multiple 60s sleeps and date calls have some overhead.
      correction=$((sleft-left))
      if (( ${correction#-} > 59 )); then
        echo "System time change detected..."
        (( sleft <= 0 )) && return # terminating as the desired time passed already
        til "$1" && return # resuming the timer anew with the new time
      fi

      # plural calculations
      (( sec > 1 )) && ss=s
      (( hm != 1 )) && ms=s
      (( h > 1 )) && hs=s

      (( h > 0 )) && printf %s "$h hour$hs and "
      (( h > 0 || hm > 0 )) && printf '%2d %s' "$hm" "minute$ms"
      if [[ $showSeconds ]]; then
        showSeconds=
        (( h > 0 || hm > 0 )) && (( sec > 0 )) && printf %s " and "
        (( sec > 0 )) && printf %s "$sec second$ss"
        echo " left..."
        (( sec > 0 )) && sleep "$sec" && left=$((left-sec)) && continue
      else
        echo " left..."
      fi
    fi
    left=$((left-60))
    sleep "$((60+correction))"
    correction=0
  done
}
Камусенсей
источник
8

Вы можете остановить выполнение процесса, отправив ему сигнал SIGSTOP, а затем заставить его возобновить выполнение, отправив ему сигнал SIGCONT.

Таким образом, вы можете остановить свой скрипт, отправив SIGSTOP:

kill -SIGSTOP <pid>

Затем используйте at deamon, чтобы разбудить его, отправив ему SIGCONT таким же образом.

Предположительно, ваш скрипт сообщит, когда он хотел проснуться, прежде чем уснуть.

SpoonMeiser
источник
8

В Ubuntu 12.04.4 LTS вот простой ввод bash, который работает:

sleep $(expr `date -d "03/21/2014 12:30" +%s` - `date +%s`)
Энтони О.
источник
7

Чтобы следовать ответу SpoonMeiser, вот конкретный пример:

$cat ./reviveself

#!/bin/bash

# save my process ID
rspid=$$

# schedule my own resuscitation
# /bin/sh seems to dislike the SIGCONT form, so I use CONT
# at can accept specific dates and times as well as relative ones
# you can even do something like "at thursday" which would occur on a 
# multiple of 24 hours rather than the beginning of the day
echo "kill -CONT $rspid"|at now + 2 minutes

# knock myself unconscious
# bash is happy with symbolic signals
kill -SIGSTOP $rspid

# do something to prove I'm alive
date>>reviveself.out
$
Приостановлено до дальнейшего уведомления.
источник
Я думаю, вы хотите запланировать SIGCONT, а не другой SIGSTOP, поэтому либо сигнал, либо комментарий неверны. В противном случае приятно видеть подходящий пример.
SpoonMeiser
Ой, я опечатал комментарий. Теперь исправлено. Но нужно смотреть, используя числовые сигналы, так как они могут быть разными.
Приостановлено до дальнейшего уведомления.
Я обнаружил, что тире, похоже, не понимает SIGCONT, поэтому сначала я использовал -18, который не является переносимым, затем я обнаружил, что ему нравится CONT, поэтому я отредактировал ответ выше, чтобы исправить это.
Приостановлено до дальнейшего уведомления.
6

Мне нужен сценарий, который проверял только часы и минуты, чтобы я мог запускать сценарий с одними и теми же параметрами каждый день. Я не хочу беспокоиться о том, какой день будет завтра. Так что я использовал другой подход.

target="$1.$2"
cur=$(date '+%H.%M')
while test $target != $cur; do
    sleep 59
    cur=$(date '+%H.%M')
done

параметры скрипта - часы и минуты, поэтому я могу написать что-то вроде:

til 7 45 && mplayer song.ogg

(til - название скрипта)

больше дней опаздывать на работу, потому что вы опечатали день. ура!

коломер
источник
4

timeToWait = $ ((конец $ - начало $))

Помните, что "timeToWait" может быть отрицательным числом! (например, если вы укажете, что нужно спать до «15:57», а теперь «15:58»). Поэтому вы должны проверить это, чтобы избежать странных ошибок сообщений:

#!/bin/bash
set -o nounset

### // Sleep until some date/time. 
# // Example: sleepuntil 15:57; kdialog --msgbox "Backup needs to be done."


error() {
  echo "$@" >&2
  exit 1;
}

NAME_PROGRAM=$(basename "$0")

if [[ $# != 1 ]]; then
     error "ERROR: program \"$NAME_PROGRAM\" needs 1 parameter and it has received: $#." 
fi


current=$(date +%s.%N)
target=$(date -d "$1" +%s.%N)

seconds=$(echo "scale=9; $target - $current" | bc)

signchar=${seconds:0:1}
if [ "$signchar" = "-" ]; then
     error "You need to specify in a different way the moment in which this program has to finish, probably indicating the day and the hour like in this example: $NAME_PROGRAM \"2009/12/30 10:57\"."
fi

sleep "$seconds"

# // End of file
Ариэль
источник
Хорошее решение, однако, я думаю, что $ SECONDS - это строка, поэтому защитный код должен быть чем-то вроде получения подстроки сначала, SIGNCHAR=${SECONDS:0:1}а затем if [ "$SIGNCHAR" = "-" ]. Это должно сработать.
H2ONaCl 04
1

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

Программист-преступник
источник
1

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

Ким Рис
источник
Ой, чувак, я как раз писал еще один ответ на этот счет.
SpoonMeiser
Ну, вообще-то нет, у меня было немного иначе.
SpoonMeiser
0

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

#!/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в другом.

Дима Тиснек
источник
Где связь с моим вопросом?
theomega
его легко продлить, чтобы untilустановить конкретную дату / время
Дима Тиснек
0
 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
Ник Константин
источник
Можете ли вы добавить какое-то описание к этому решению?
cdomination
это сценарий bash; функция sleepuntil принимает один аргумент; вы устанавливаете переменную target_time = "11:59" или любое другое время, до которого хотите спать; затем вы вызываете функцию с аргументом target_time. Он подсчитывает, сколько секунд осталось до указанного времени, и засыпает на это количество секунд
Ник Константин
0

Для этого я собрал небольшую утилиту под названием Hypnos . Он настроен с использованием синтаксиса crontab и до этого времени блокируется.

#!/bin/bash
while [ 1 ]; do
  hypnos "0 * * * *"
  echo "running some tasks..."
  # ...
done
Крис Фостер
источник
0

Чтобы расширить основной ответ, вот несколько действительных примеров, касающихся манипуляции строкой даты:

sleep $(($(date -f - +%s- <<< $'+3 seconds\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'3 seconds\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'3 second\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'+2 minute\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'tomorrow\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'tomorrow 21:30\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'3 weeks\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'3 week\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'next Friday 09:00\nnow')0)) && ls

sleep $(($(date -f - +%s- <<< $'2027-01-01 00:00:01 UTC +5 hours\nnow')0)) && ls
NVRM
источник
-1

В 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что для минутной спецификации требуется ровно две цифры.

cnst
источник
-2

Используйте tarry. Это инструмент, который я написал специально для этого.

https://github.com/metaphyze/tarry/

Это простой инструмент командной строки для ожидания определенного времени. Это не то же самое, что «сон», который ждет некоторое время. Это полезно, если вы хотите выполнить что-то в определенное время или, что более вероятно, выполнить несколько действий в одно и то же время, например, для тестирования, может ли сервер обрабатывать несколько очень одновременных запросов. Вы можете использовать это так с "&&" в Linux, Mac или Windows:

   tarry -until=16:03:04 && someOtherCommand

Это будет ждать до 16:03:04, а затем выполнить someOtherCommand. Вот пример Linux / Mac того, как запустить несколько запросов, запуск которых запланирован на одно и то же время:

   for request in 1 2 3 4 5 6 7 8 9 10
   do
       tarry -until=16:03:04 && date > results.$request &
   done

Бинарные файлы Ubuntu, Linux и Windows доступны по ссылкам на странице.

метафиз
источник