Belirli bir saate / tarihe kadar uyu


92

Bash betiğimin belirli bir saate kadar uyumasını istiyorum. Bu yüzden, "uyku" gibi aralıksız bitiş zamanı olan ve o zamana kadar uyuyan bir komut istiyorum.

Çalışan bir betiği belirli bir tarihe / saate kadar engellemem gerektiğinden, "at" -daemon bir çözüm değil.

Böyle bir emir var mı?


1
Bir hesaplamadan önce uzun bir uyku kullanan çözümün çok uzun, özellikle de hazırda bekletilebilen bir makineniz varsa çok uzun süre uyuyabileceğini unutmayın. Posix uyku komutu, çok uzun süre uyumayacağına dair hiçbir söz vermez. @Camusensei'nin çözümü endişeyi çok güzel bir şekilde ele alıyor.
GregD

Yanıtlar:


101

Outlaw Programmer tarafından belirtildiği gibi, çözümün doğru saniye kadar uyumak olduğunu düşünüyorum.

Bunu bash'ta yapmak için aşağıdakileri yapın:

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

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

sleep $sleep_seconds

Nanosaniyelere kadar hassasiyet eklemek için (milisaniyeler civarında daha etkili bir şekilde) şu sözdizimini kullanın:

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'in saniyenin altındaki hassasiyeti desteklemediğini coreutils, brewbunun yerine kullanmanız gerekeceğini unutmayın → bu talimatlara bakın


8
Bunun için teşekkürler, "sleepuntil" komutunu almak için küçük bir kabuk betiği yazdım.
theomega

1
@enigmaticPhysicist: Eşzamansız çalışan benzer bir "at" komut çağrısı var.
voidlogic

8
Yarın saat 03: 00'te durdurmak istiyorsanız, target_epoch=$(date -d 'tomorrow 03:00' +%s)bunun yerine kullanabilirsiniz .
Yajo

dateİkisi yerine bir çatal kullanarak da aynısını yapabilirsiniz ! Cevabımın
F. Hauri

1
Bu çözümün potansiyel olarak çok uzun süre uyuyabileceğini ve makineniz biraz hazırda bekletirse çok uzun sürebileceğini unutmayın.
GregD

26

Bu soru 4 yıl önce sorulduğu için, bu ilk bölüm eski bash sürümleriyle ilgilidir :

Son düzenleme: 22 Nisan 2020, Çar, 10:30 ile 10:00 saatleri arasında: 55 (Örnekleri okumak için önemlidir)

Genel yöntem (Yararsız çatallardan kaçının!)

(Nota: Bu yöntem kullanılırken date -f! Hayır POSIX ve Mac altında MacOS If altında işlerine yok wich benim goto, safişlevi )

Azaltmak için iki kez forksçalıştırmak yerine şunu datekullanmayı tercih ediyorum:

Basit başlangıç ​​örneği

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

Nerede tomorrow 21:30tarafından tanınan tarih ve biçimi her türlü yerini olabilir dategelecekte.

Yüksek hassasiyetle (nanosec)

Hemen hemen aynı:

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

Bir dahaki sefere ulaşıyorum

Mümkünse bugün, çok geç ise yarın sonrakiHH:MM anlama ulaşmak için :

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

Bu altında çalışır , ve diğer modern mermiler, ancak kullanmanız gerekir:

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

gibi daha hafif kabukların altında veya .

Saf yol, çatal yok !!

MacOS altında test edildi!

Bir iki küçük işlev yazdım : sleepUntilvesleepUntilHires

 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'in yeni sürümleri, printftarihi alma seçeneği sunduğundan , HH: MM'ye kadar uykunun bu yeni yolu için, kullanmadan dateveya başka bir çatal kullanmadan, biraz geliştirdimişlevi. İşte burada:

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
}

Sonra:

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

Hedef ise daha önce yarına kadar bu irade uyku:

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 ile zaman GNU / Linux altında

Son 5.0 sürümünden itibaren $EPOCHREALTIMEmikrosaniye ile yeni değişken ekleyin . Bundan bir sleepUntilHiresişlev var.

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
}

Lütfen unutmayın: bu kullanım read -tyerleşiktir, yerine yerleşiktir sleep. Maalesef, gerçek TTY olmadan arka planda çalışırken bu işe yaramaz. Yerine çekinmeyin read -ttarafından sleepsize ... (Ama arka plan süreci için kullanarak düşünün arkaplan script içindeki çalıştırmayı planlıyorsanız cronve / veya atyerine bütün bunların)

Testler ve uyarılar için sonraki paragrafı atlayın $ËPOCHSECONDS!

Son çekirdek /proc/timer_listkullanıcı tarafından kullanmaktan kaçının !!

En son Linux çekirdeği altında, ** nanosaniye ** içinde bir "offset" ve "now" değişkenini okuyabileceğiniz "/ proc / timer_list" adlı bir değişken dosyası bulacaksınız. Böylece, istenen * en üst * zamana ulaşmak için uyku süresini hesaplayabiliriz.

(Bunu, bir saniye için bin satır içeren çok büyük günlük dosyalarında belirli olayları oluşturmak ve izlemek için yazdım).

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
}

İki salt okunur değişkeni tanımladıktan sonra TIMER_LIST_OFFSETve TIMER_LIST_SKIPişlev, /proc/timer_listuyku süresini hesaplamak için değişken dosyasına çok hızlı bir şekilde erişecektir :

Küçük test işlevi

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
}

Şunun gibi bir şey oluşturabilir:

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
  • Sonraki saniyenin başında,
  • baskı zamanı, sonra
  • 0,92 saniye bekleyin, sonra
  • baskı zamanı, sonra
  • 0.07 saniye kaldı, sonraki saniyeye hesapla
  • 0,07 saniye uyu, sonra
  • baskı süresi.

Karıştırmamaya özen gösterin $EPOCHSECONDve $EPOCHREALTIME!

Ve arasındaki fark hakkındaki uyarımı oku$EPOCHSECOND$EPOCHREALTIME

Bu işlev kullanılır, $EPOCHREALTIMEbu nedenle sonraki saniyeyi$EPOCHSECOND oluşturmak için kullanmayın :

Örnek sorun: Sonraki 2 saniyeye yuvarlanan süreyi yazdırmaya çalışma:

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

Üretebilir:

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
Vaov! Bilgisayar nanosaniye altında bash !
F. Hauri

Yerel bash v5 + altında mikro saniye hesaplama !!
F. Hauri

Bilgiçlik taslayan not: %86400hile yalnızca iki zaman bir gün ışığından yararlanma saati geçişini kapsamıyorsa işe yarar.
200_success

@ 200_success Zaman farkı uygulayabilirsiniz: Cevabımda ara tzoff!
F.Hauri

21

Kullan sleep, ancak zamanı kullanarak hesapla date. Bunun için kullanmak isteyeceksiniz date -d. Örneğin, önümüzdeki haftaya kadar beklemek istediğinizi varsayalım:

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

"Gelecek hafta" yerine beklemek istediğiniz tarihi yazın, ardından bu ifadeyi bir değere atayın ve o kadar saniye uyuyun:

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

Hepsi tamam!


TimeToWait = expr ... doğrudan çalışmayacağından ve iç içe geçmeyecekleri için backticks kullanamayacağınız için, değeri bir değişkene nasıl atayacağınızı genişletmeye değer, bu yüzden $ kullanmanız gerekecek () veya geçici değişkenler.
SpoonMeiser

İyi bir öneri; Bunu daha net hale getirmek için benimkini değiştireceğim, böylece insanlar yanlış fikirlere kapılmasınlar.
John Feminella

Not -d, bugüne kadar POSIX olmayan bir uzantıdır. FreeBSD'de, gün ışığından yararlanma saati için çekirdeğin değerini ayarlamaya çalışır.
Dave C

9

İşte işi yapan VE kullanıcıya ne kadar zaman kaldığını bildiren bir çözüm. Gece boyunca komut dosyalarını çalıştırmak için neredeyse her gün kullanıyorum ( cronwindows üzerinde çalışamadığım için cygwin kullanarak )

Özellikleri

  • Saniyeye kadar hassas
  • Sistem zamanı değişikliklerini algılar ve uyarlar
  • Ne kadar zaman kaldığını söyleyen akıllı çıktı
  • 24 saatlik giriş biçimi
  • zincirleme yapabilmek için true döndürür &&

Örnek çalışma

$ 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

(Sondaki tarih, işlevin bir parçası değildir, ancak nedeniyle && date)

Kod

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

Bir SIGSTOP sinyali göndererek bir işlemin yürütülmesini durdurabilir ve ardından bir SIGCONT sinyali göndererek yürütmeye devam etmesini sağlayabilirsiniz.

Böylece komut dosyanızı bir SIGSTOP göndererek durdurabilirsiniz:

kill -SIGSTOP <pid>

Ve sonra aynı şekilde bir SIGCONT göndererek onu uyandırmak için at deamon'u kullanın.

Muhtemelen, senaryonuz kendini uykuya yatırmadan önce ne zaman uyandırılmak istendiğini bildirecektir.


8

Ubuntu 12.04.4 LTS'de, işte çalışan basit bash girişi:

sleep $(expr `date -d "03/21/2014 12:30" +%s` - `date +%s`)

7

SpoonMeiser'ın cevabını takip etmek için işte belirli bir örnek:

$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
$

Sanırım başka bir SIGSTOP yerine bir SIGCONT programlamak istiyorsunuz, yani sinyal veya yorum yanlış. Aksi takdirde, uygun bir örnek görmek güzel.
SpoonMeiser

Oops, yorumu yazdım. Şimdi düzeltildi. Ancak farklı olabileceği için sayısal sinyalleri kullanarak izlemelisiniz.
Dennis Williamson

Dash'in SIGCONT'u anlamadığını fark ettim, bu yüzden ilk başta taşınabilir olmayan -18 kullandım, sonra CONT'yi sevdiğini buldum, bu yüzden bunu düzeltmek için yukarıdaki cevabı düzenledim.
Dennis Williamson

6

Sadece saatleri ve dakikaları kontrol eden bir komut dosyası istedim, böylece komut dosyasını her gün aynı parametrelerle çalıştırabilirdim. Yarın hangi günün olacağı konusunda endişelenmek istemiyorum. Bu yüzden farklı bir yaklaşım kullandım.

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

betiğin parametreleri saatler ve dakikalardır, bu yüzden şöyle bir şey yazabilirim:

til 7 45 && mplayer song.ogg

(til, senaryonun adıdır)

İş yerinde daha fazla gün geç kalmayın çünkü günü yanlış yazdınız. şerefe!


4

timeToWait = $ (($ end - $ başlangıç))

"TimeToWait" in negatif bir sayı olabileceğine dikkat edin! (örneğin, "15:57" ye kadar uyumayı belirtirseniz ve şimdi "15:58" olur). Bu nedenle, garip mesaj hatalarından kaçınmak için kontrol etmeniz gerekir:

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

Defansif kod almak gibi bir şey olmalıdır, böylece iyi bir çözüm, ancak, $ SANİYE düşünmek bir dize birinci şöyle alt dize SIGNCHAR=${SECONDS:0:1}ve sonra if [ "$SIGNCHAR" = "-" ]. Bunu yapmalı.
H2ONaCl

1

Şimdi ile uyanma zamanı arasındaki saniye sayısını hesaplayabilir ve mevcut 'uyku' komutunu kullanabilirsiniz.


1

O sinyali bekleyen senaryonuza bir sinyal göndermek için 'at' kullanabilirsiniz.


Aww adamım, ben sadece bu etkiye başka bir cevap yazıyordum.
SpoonMeiser

Aslında, hayır, benimki biraz farklıydı.
SpoonMeiser


0

Birden çok test istemcisini senkronize etmek için şimdi yazdığım bir şey:

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

Bu komut dosyası, bir sonraki "yuvarlak" veya "keskin" zamana kadar uyur.

Basit bir kullanım durumu, ./sleep.py 10; ./test_client1.pybir terminalde ve diğerinde çalıştırmaktır ./sleep.py 10; ./test_client2.py.


Sorumla bağlantı nerede?
theomega

untilbelirli bir tarihe / saate ayarlanması için uzatması kolaydır
Dima Tisnek

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

Bu çözüme bir çeşit açıklama ekleyebilir misiniz?
cdomination

bu bir bash betiğidir; işlev uykusu bir argüman alana kadar; target_time = "11:59" değişkenini veya ne kadar uyumak istediğinizi ayarlarsınız; daha sonra işlevi target_time bağımsız değişkeniyle çağırırsınız. Hedef zamana kaç saniye kaldığını hesaplar ve bu kadar saniye boyunca uyur
Nick Constantine

0

Bunu yapmak için Hypnos adında küçük bir yardımcı program oluşturdum . Crontab sözdizimi kullanılarak yapılandırılır ve o zamana kadar engeller.

#!/bin/bash
while [ 1 ]; do
  hypnos "0 * * * *"
  echo "running some tasks..."
  # ...
done

0

Ana yanıtı genişletmek için, işte tarih dizesi manipülasyonuyla ilgili bazı geçerli örnekler:

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

-1

On OpenBSD , şu bir sıkıştırmak için kullanılabilir */55 dakikalık crontab(5)bir içine işi 00(tam aralıklarla aynı görevi yerine getirirken, emin az e-postalar oluşturulan tüm yapmak) saatlik one:

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

Dakikalar geçerli bir zaman olmadığından (aksi takdirde!) Son yinelemede tasarıma göre date(1)bozulacağını unutmayın , bu nedenle e-posta raporumuzu almadan önce fazladan bir süre beklemek zorunda kalmayacağız.sleep(1)60

Ayrıca, yinelemelerden birinin kendisine ayrılan 5 dakikadan fazla sürmesi durumunda sleep, aynı şekilde, hiç uyumayarak tasarım gereği nezaketle başarısız olacağını da unutmayın (bunun yerine, bir komut satırı seçeneği olarak yorumlanan negatif bir sayı olması nedeniyle, sonraki saat veya sonsuzluk), böylece işinizin ayrılan saat içinde tamamlanabileceğinden emin olun (örneğin, yinelemelerden yalnızca biri 5 dakikadan biraz fazla sürerse, o zaman yetişmek için hala vaktimiz olur. bir sonraki saate dolan herhangi bir şey).

printf(1)Gerekli olduğundan datebeklentiden dakika özellikleri için tam olarak iki basamaklı.


-2

Katran kullanın. Özellikle bunu yapmak için yazdığım bir araç.

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

Bu, belirli bir zamana kadar beklemek için basit bir komut satırı aracıdır. Bu, bir süre bekleyecek olan "uyku" ile aynı şey değildir. Bu, bir şeyi belirli bir zamanda yürütmek istiyorsanız veya bir sunucunun aynı anda birden çok isteği işleyip işlemediğini test etmek gibi daha büyük olasılıkla aynı anda birkaç şeyi yürütmek istiyorsanız kullanışlıdır. Linux, Mac veya Windows'ta "&&" ile şu şekilde kullanabilirsiniz:

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

Bu, 4: 03: 04'e kadar bekler ve daha sonra Diğer Komutları çalıştırır. Tümünün aynı anda başlaması planlanan birden çok isteğin nasıl çalıştırılacağına ilişkin bir Linux / Mac örneği:

   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 ve Windows ikili dosyalarına sayfadaki bağlantılardan ulaşılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.