एक निश्चित समय / तिथि तक सोएं


92

मैं चाहता हूं कि मेरी बैश स्क्रिप्ट एक विशिष्ट समय तक सो जाए। इसलिए, मुझे "स्लीप" जैसी कमांड चाहिए, जिसमें कोई अंतराल न हो लेकिन अंत समय हो और तब तक सोता रहे।

"पर" -demon एक समाधान नहीं है, क्योंकि मुझे एक निश्चित तिथि / समय तक एक रनिंग स्क्रिप्ट को ब्लॉक करने की आवश्यकता है।

क्या ऐसी कोई आज्ञा है?


1
ध्यान दें कि एक गणना से पहले एक लंबी नींद का उपयोग करने वाले समाधान बहुत लंबे समय तक सो सकते हैं, शायद बहुत लंबे समय तक विशेष रूप से यदि आपके पास एक मशीन है जो हाइबरनेट जा सकती है। पॉज़िक्स स्लीप कमांड बहुत लंबे समय तक नहीं सोने के बारे में कोई वादा नहीं करता है। @Camusensei द्वारा समाधान चिंता को बहुत अच्छी तरह से संबोधित करता है।
GregD

जवाबों:


101

जैसा कि डाकू प्रोग्रामर ने उल्लेख किया है, मुझे लगता है कि समाधान केवल सही संख्या में सेकंड के लिए सोना है।

बैश में ऐसा करने के लिए, निम्न कार्य करें:

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 / ओएस एक्स सेकंड नीचे परिशुद्धता का समर्थन नहीं करता है, तो आप का उपयोग करने की आवश्यकता होगी coreutilsसे brew→ बजाय ये निर्देश देखें


8
इसके लिए धन्यवाद, मैंने "स्लीपंटिल" कमांड प्राप्त करने के लिए एक छोटी सी शेल-स्क्रिप्ट लिखी।
ओमेगा

1
@enigmaticPhysicist: "at" पर एक समान कमांड कॉल है, जो async चलाता है।
voidlogic

8
यदि आप कल 3 बजे बंद करना चाहते हैं, तो आप target_epoch=$(date -d 'tomorrow 03:00' +%s)इसके बजाय उपयोग कर सकते हैं ।
यजो

आप dateदो के बजाय एक कांटा का उपयोग करके ऐसा कर सकते हैं ! मेरे जवाब
F. Hauri

1
ध्यान दें कि यह समाधान संभावित रूप से बहुत लंबा सो सकता है, और यदि आपकी मशीन थोड़ा सा हाइबरनेट करती है, तो यह बहुत लंबा हो सकता है।
GregD

26

जैसा कि यह सवाल 4 साल पहले पूछा गया था, यह पहला हिस्सा पुराने बैश संस्करणों की चिंता करता है:

अंतिम संपादन: बुध अप्रैल २२ २०२०, १०:३० से १० बजे के बीच कुछ: ५५ (नमूने पढ़ने के लिए महत्वपूर्ण)

सामान्य विधि (बेकार कांटे से बचें!)

(नोट: इस विधि का उपयोग date -fविच कोई पोसिक्स नहीं है और मैकओएस के तहत काम नहीं करते हैं! यदि मैक के तहत, मेरा शुद्ध गोटो हैसमारोह )

कम करने के लिए 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)

बैश के नए संस्करणों के रूप में 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उपयोगकर्ता द्वारा उपयोग करने से बचें !!

हाल ही में लिनक्स कर्नेल के तहत, आपको एक वेरिएबल फ़ाइल मिलेगी, जिसका नाम `/ proc / टाइमर_लिस्ट` है, जहां आप ** नैनोसेकंड ** में एक` ऑफसेट` और `अब` वेरिएबल पढ़ सकते हैं। इसलिए हम सोने के समय की गणना * बहुत ऊपर * वांछित समय तक करने के लिए कर सकते हैं।

(मैंने इसे बहुत बड़ी लॉग फ़ाइलों पर विशिष्ट घटनाओं को उत्पन्न करने और ट्रैक करने के लिए लिखा था, जिसमें एक सेकंड के लिए हजार लाइन शामिल हैं)।

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
वाह! बास के तहत नैनोसेकंड की गणना !
एफ। हौरी

देशी बैश v5 + के तहत माइक्रो सेकंड कम्प्यूटिंग !!
एफ। हौरी

पेडिटिक नोट: %86400ट्रिक केवल तभी काम करती है जब दो बार डेलाइट सेविंग टाइम ट्रांजिशन न हो।
२००

@ 200_success आप समय ऑफसेट लागू कर सकते हैं: tzoffमेरे उत्तर के लिए खोजें !
एफ। हौरी डेसी

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 ... सीधे काम नहीं करेगा, और आप बैकस्टिक्स का उपयोग नहीं कर सकते क्योंकि वे घोंसला नहीं बनाएंगे, इसलिए आपको $ का उपयोग करना होगा (), या अस्थायी चर।
स्पूनमाइजर

अच्छा सुझाव; मैं उस स्पष्ट करने के लिए मेरा संशोधन करूंगा ताकि लोगों को गलत विचार न आए।
जॉन फेमिनेला

नोट -dआज तक एक गैर-POSIX एक्सटेंशन है। FreeBSD पर यह डेलाइट सेविंग टाइम के लिए कर्नेल का मान सेट करने का प्रयास करता है।
डेव सी

9

यहाँ एक समाधान है जो काम करता है और उपयोगकर्ता को सूचित करता है कि कितना समय शेष है। मैं इसे लगभग रोज़ रात के दौरान स्क्रिप्ट चलाने के लिए उपयोग करता हूं (साइबरविन का उपयोग करके, जैसा कि मुझे नहीं मिलाcron खिड़कियों पर काम करने के लिए )

विशेषताएं

  • दूसरे के लिए सटीक नीचे
  • सिस्टम का समय परिवर्तन और अनुकूलन का पता लगाता है
  • बुद्धिमान आउटपुट बता रहा है कि कितना समय बचा है
  • 24 घंटे का इनपुट प्रारूप
  • के साथ चेन करने में सक्षम होने के लिए सही रिटर्न &&

नमूना चला

$ 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 सिग्नल भेजकर फिर से निष्पादित करना शुरू कर सकते हैं।

इसलिए आप अपनी स्क्रिप्ट को भेजने से रोक सकते हैं एक हस्ताक्षर है:

kill -SIGSTOP <pid>

और फिर इसे उसी तरह SIGCONT भेजकर इसे जगाने के लिए deamon में उपयोग करें।

संभवतः, आपकी स्क्रिप्ट उस समय सूचित करेगी जब वह सोने से पहले खुद को जगाना चाहता था।


8

Ubuntu 12.04.4 LTS पर यहां सरल बैश इनपुट है जो काम करता है:

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

7

स्पूनमाइज़र के उत्तर का पालन करने के लिए, यहाँ एक विशिष्ट उदाहरण दिया गया है:

$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 को समझ नहीं पा रहा है, इसलिए पहले मैंने -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

(तिल स्क्रिप्ट का नाम है)

कोई और अधिक दिन काम के कारण देर से आप दिन गलत समझे। चियर्स!


4

timeToWait = $ (($ अंत - $ start))

सावधान रहें कि "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

1

आप अब और वेक-अप समय के बीच सेकंड की संख्या की गणना कर सकते हैं और मौजूदा 'स्लीप' कमांड का उपयोग कर सकते हैं।


1

आप शायद अपनी स्क्रिप्ट को एक संकेत भेजने के लिए 'at' का उपयोग कर सकते हैं, जो उस संकेत की प्रतीक्षा कर रहा था।


Aww आदमी, मैं सिर्फ इस आशय का एक और जवाब लिख रहा था।
स्पूनमाइजर

खैर, वास्तव में, नहीं, मेरा थोड़ा अलग था।
स्पूनमाइज़र

1

मैंने वास्तव में इस सटीक उद्देश्य के लिए https://tamentis.com/projects/sleepuntil/ लिखा था । यह BSD से आता है, 'यह काफी मानक-अनुरूप है, अधिकांश कोड थोड़ा-सा मारता है:

$ sleepuntil noon && sendmail something


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दूसरे में चलाना है ।


मेरे प्रश्न का संबंध कहां है?
ओमेगा

इसका विस्तार इतना आसान है कि 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

यह एक बैश स्क्रिप्ट है; फ़ंक्शन स्लीपंटिल एक तर्क लेता है; आप परिवर्तनशील लक्ष्य_टाइम = "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

-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मिनट विनिर्देश के लिए वास्तव में दो अंकों की उम्मीद है।


-2

टैरी का उपयोग करें। यह एक ऐसा उपकरण है जिसे मैंने विशेष रूप से ऐसा करने के लिए लिखा है।

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

यह एक विशिष्ट समय तक प्रतीक्षा करने के लिए एक सरल कमांड लाइन उपकरण है। यह "नींद" के समान नहीं है जो समय की अवधि के लिए इंतजार करेगा। यह उपयोगी है यदि आप किसी विशिष्ट समय पर कुछ निष्पादित करना चाहते हैं या अधिक संभावना है कि ठीक उसी समय कई चीजें निष्पादित करें जैसे कि परीक्षण यदि कोई सर्वर एक साथ बहुत अधिक अनुरोधों को संभाल सकता है। आप इसे लिनक्स, मैक या विंडोज पर "&&" के साथ इस तरह उपयोग कर सकते हैं:

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

यह 4:03:04 बजे तक इंतजार करेगा और फिर कुछ ऑथरकोमांड को अंजाम देगा। एक ही समय में शुरू करने के लिए सभी अनुरोधों को चलाने के लिए लिनक्स / मैक उदाहरण यहां दिया गया है:

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

पेज पर लिंक के माध्यम से उबंटू, लिनक्स और विंडोज बायनेरिज़ उपलब्ध हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.