নির্দিষ্ট সময় / তারিখ পর্যন্ত ঘুমান


92

আমি চাই আমার বাশ স্ক্রিপ্টটি একটি নির্দিষ্ট সময় পর্যন্ত ঘুমানো উচিত। সুতরাং, আমি "ঘুম" এর মতো একটি কমান্ড চাই যা অন্তর শেষ না হয়ে শেষ সময় নেয় এবং ততক্ষণ ঘুমায়।

"এট" -ডেমোনের কোনও সমাধান নয়, কারণ আমার একটি নির্দিষ্ট তারিখ / সময় পর্যন্ত চলমান স্ক্রিপ্টটি ব্লক করা দরকার।

এমন আদেশ আছে কি?


4
দ্রষ্টব্য যে সমাধানটি কেবল গণনার আগে দীর্ঘ দীর্ঘ ঘুম ব্যবহার করে খুব বেশি দীর্ঘ ঘুম হতে পারে, বিশেষত আপনার যদি এমন কোনও মেশিন থাকে যা হাইবারনেট করতে পারে। পোস্টিক্স স্লিপ কমান্ড খুব বেশি সময় না ঘুমানোর বিষয়ে কোনও প্রতিশ্রুতি দেয় না। @ ক্যামুসেনসি এর সমাধানটি উদ্বেগকে খুব সুন্দরভাবে সম্বোধন করেছে।
গ্রেগডি

উত্তর:


101

আউটলা প্রোগ্রামার দ্বারা উল্লিখিত হিসাবে, আমি মনে করি সমাধানটি কেবলমাত্র সঠিক সেকেন্ডের জন্য ঘুমানো sleep

ব্যাশে এটি করতে, নিম্নলিখিতটি করুন:

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 এর সেকেন্ড নিচে স্পষ্টতা সমর্থন করে না, আপনি ব্যবহার করতে হবে coreutilsথেকে brew→ পরিবর্তে এই নির্দেশাবলী দেখুন


8
তার জন্য ধন্যবাদ, আমি "স্লিপুনটিল" কমান্ড পেতে একটি ছোট শেল-স্ক্রিপ্ট লিখেছি।
থিওমেগা

4
@ এনজিমেটিক ফিজিসিস্ট: "এট" তেমন অনুরূপ কমান্ড কল রয়েছে যা এসিএনসি চালায়।
অযৌক্তিক

8
আপনি যদি আগামীকাল সকাল 3 টায় থামতে চান তবে আপনি তার target_epoch=$(date -d 'tomorrow 03:00' +%s)পরিবর্তে ব্যবহার করতে পারেন ।
ইয়াজো

আপনি dateদুটি পরিবর্তে একটি কাঁটাচামচ ব্যবহার করে একই কাজ করতে পারেন ! আমার উত্তরের
এফ। হাউরি

4
নোট করুন যে এই সমাধানটি সম্ভাব্যভাবে খুব দীর্ঘ ঘুমাতে পারে এবং যদি আপনার মেশিনটি কিছুটা হাইবারনেট করে তবে এটি অনেক দীর্ঘ হতে পারে।
গ্রেগডি

26

4 বছর আগে এই প্রশ্নটি যেমন জিজ্ঞাসা করা হয়েছিল, এই প্রথম অংশটি পুরানো বাশ সংস্করণ নিয়ে উদ্বেগ প্রকাশ করেছে :

শেষ সম্পাদনা: 22 এপ্রিল 222020, 10:30 থেকে 10 ঘন্টা: 55 এর মধ্যে কিছু (নমুনা পড়ার জন্য গুরুত্বপূর্ণ)

সাধারণ পদ্ধতি (অকেজো কাঁটাচামচ এড়ান!)

(নোটা: এই পদ্ধতিটি ব্যবহার করুন 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

হাইআরসের সাথে সময় জিএনইউ / লিনাক্সের অধীনে

সাম্প্রতিক সংস্করণ 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 / timer_list` নামের একটি ভেরিয়েবল ফাইল পাবেন যেখানে আপনি ** ন্যানোসেকেন্ডস **-তে একটি অফসেট এবং একটি` নাও-ভেরিয়েবল পড়তে পারেন। সুতরাং আমরা * খুব শীর্ষ * কাঙ্ক্ষিত সময়ে পৌঁছতে ঘুমের সময় গণনা করতে পারি।

(আমি এক সেকেন্ডের জন্য হাজার লাইনের সমন্বয়ে খুব বড় লগ ফাইলগুলিতে নির্দিষ্ট ইভেন্টগুলি তৈরি এবং ট্র্যাক করতে এটি লিখেছিলাম)।

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

4
কি দারুন! কম্পিউটিং ন্যানোসেকেন্ড অধীনে ব্যাশ !
এফ হাউরি

নেটিভ বাশ ভি 5 এর অধীনে মাইক্রো সেকেন্ড গণনা করা হচ্ছে !!
এফ। হাউরি

পেডেন্টিক নোট: %86400কৌশলটি কেবল তখনই কাজ করে যদি দুটি সময় দিবালোকের সময় সাশ্রয় করে সময় সঞ্চালন করে না।
200_সাক্সেস

@ 200_সুকসেস আপনি অফসেটের সময় প্রয়োগ করতে পারেন: 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

সব শেষ!


আপনি কীভাবে কোনও ভেরিয়েবলের মান নির্ধারণ করবেন তা প্রসারিত করার মতো, যেহেতু টাইমওয়েট = এক্সপ্রেস ... সরাসরি কাজ করবে না, এবং আপনি ব্যাকটিকগুলি ব্যবহার করতে পারবেন না কারণ তারা বাসা বাঁধবে না, তাই আপনাকে ব্যবহার করতে হবে $ (), বা অস্থায়ী পরিবর্তনশীল।
চামচমাইজার

ভাল পরামর্শ; আমি আরও পরিষ্কার করে তুলতে আমার পরিবর্তন করব যাতে লোকেরা ভুল ধারণা না পায়।
জন Feminella

নোটটি -dআজ অবধি একটি পসিক্স এক্সটেনশান। ফ্রিবিএসডি-তে এটি দিবালোকের সময় সাশ্রয়ের জন্য কার্নেলের মান সেট করার চেষ্টা করে।
ডেভ সি

9

এখানে একটি সমাধান যা কাজটি করে এবং ব্যবহারকারীকে কতটা সময় বাকি তা অবহিত করে। আমি এটি প্রায় প্রতিদিন রাতে স্ক্রিপ্টগুলি চালানোর জন্য ব্যবহার করি (সাইগউইন ব্যবহার করে, আমি cronউইন্ডোতে কাজ করতে পারি নি )

বৈশিষ্ট্য

  • যথার্থ দ্বিতীয় থেকে নীচে
  • সিস্টেমের সময় পরিবর্তনগুলি এবং অ্যাডাপ্টগুলি সনাক্ত করে
  • বুদ্ধিমান আউটপুট বলছে কত সময় বাকি
  • 24 ঘন্টা ইনপুট ফর্ম্যাট
  • সাথে চেইন করতে সক্ষম হতে সত্য ফিরে আসে returns &&

নমুনা রান

$ 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

আপনি একটি সিগস্টপ সিগন্যাল প্রেরণ করে কোনও প্রক্রিয়া কার্যকর করতে বাধা দিতে পারেন এবং তারপরে এটি একটি সিগন্যাক্ট সিগন্যাল প্রেরণ করে পুনরায় কার্যকর করা শুরু করতে পারেন।

সুতরাং আপনি প্রেরণ করে আপনার স্ক্রিপ্টটি থামিয়ে দিতে পারেন একটি সাইনস্টপ:

kill -SIGSTOP <pid>

এবং তারপরে এটি একইভাবে একটি সাইনকন্ট প্রেরণ করে এটি জাগ্রত করতে ডিটামনে ডিমন ব্যবহার করুন।

সম্ভবত, আপনার স্ক্রিপ্টটি ঘুমের আগে নিজেকে কখন ঘুম থেকে উঠতে চেয়েছিল তা অবহিত করবে।


8

উবুন্টুতে 12.04.4 এলটিএসে এখানে সরল বাশ ইনপুট যা কাজ করে:

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
$

আমি মনে করি আপনি অন্য একটি সিগস্টপের চেয়ে একটি সিগকন্ট শিডিউল করতে চান, সুতরাং সিগন্যাল হয়, বা মন্তব্যটি ভুল। অন্যথায়, একটি সঠিক উদাহরণ দেখতে ভাল লাগল।
চামচমাইজার

ওফস, আমি মন্তব্যটি টাইপ করেছি। এখন স্থির। তবে আপনাকে সংখ্যার সিগন্যাল ব্যবহার করে দেখতে হবে, যেহেতু এগুলি আলাদা হতে পারে।
ডেনিস উইলিয়ামসন

আমি দেখতে পেয়েছি যে ড্যাশগুলি সিগকন্টটি বুঝতে পারে না বলে মনে হয়, তাই প্রথমে আমি -18 ব্যবহার করেছি যা অ-বহনযোগ্য,
ডেনিস উইলিয়ামসন

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

টাইমটোয়াইট = $ (($ শেষ - $ শুরু))

সাবধান থাকুন যে "টাইমটোয়েট" কোনও নেতিবাচক সংখ্যা হতে পারে! (উদাহরণস্বরূপ, আপনি যদি "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

ভাল সমাধান, তবে আমি মনে করি $ সেকেন্ডস একটি স্ট্রিং তাই ডিফেন্সিভ কোডটি এমন কিছু হওয়া উচিত যা প্রথমে প্রথমে একটি স্ট্রিংিং পেয়ে যায় SIGNCHAR=${SECONDS:0:1}এবং তারপরে if [ "$SIGNCHAR" = "-" ]। যা করা উচিৎ.
H2ONaCl

1

আপনি এখন এবং জাগ্রত সময়ের মধ্যে সেকেন্ডের সংখ্যা গণনা করতে পারেন এবং বিদ্যমান 'স্লিপ' কমান্ডটি ব্যবহার করতে পারেন।


1

আপনার স্ক্রিপ্টে একটি সংকেত প্রেরণের জন্য আপনি সম্ভবত 'এট' ব্যবহার করতে পারেন, যা সেই সংকেতের অপেক্ষায় বসে ছিল।


ওহ মানুষ, আমি এই প্রভাবটির জন্য আরও একটি উত্তর লিখেছিলাম।
চামচমাইজার

আসলে, না, আমার কিছুটা আলাদা ছিল।
স্পুনমাইজার

1

আমি প্রকৃতপক্ষে এই সঠিক উদ্দেশ্যে https://tamentis.com / প্রকল্পগুলি / স্লিপুনটিল / লিখেছি । এটি বেশিরভাগ কোডকে 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

আপনি কি এই সমাধানটিতে কিছু ধরণের বর্ণনা যুক্ত করতে পারেন?
আধিপত্য

এটি বাশ লিপি; ফাংশন স্লিপুনটিল একটি যুক্তি গ্রহণ করে; আপনি ভেরিয়েবল টার্গেট_টাইম = "11:59" সেট করেছেন বা আপনি যতক্ষণ ঘুমাতে চান সময় অবধি; তারপরে আপনি টার্গেট_টাইম যুক্তি দিয়ে ফাংশনটি কল করবেন। এটি লক্ষ্যমাত্রার সময় পর্যন্ত কত সেকেন্ডের গণনা করে এবং সেই পরিমাণ সেকেন্ডের জন্য ঘুমায়
নিক কনস্টান্টাইন

0

এটি করার জন্য আমি Hypnos নামক একটি ছোট্ট ইউটিলিটি একসাথে রেখেছি । এটি ক্রন্টাব সিনট্যাক্স এবং সেই সময় অবধি ব্লক ব্যবহার করে কনফিগার করা হয়েছে।

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

নির্দিষ্ট সময় পর্যন্ত অপেক্ষা করার জন্য এটি একটি সাধারণ কমান্ড লাইন সরঞ্জাম। এটি "ঘুম" এর মতো নয় যা সময়ের জন্য অপেক্ষা করবে। আপনি যদি কোনও নির্দিষ্ট সময়ে কোনও কিছু কার্যকর করতে চান বা ঠিক একই সময়ে বেশ কয়েকটি জিনিস চালিত করতে চান যেমন সার্ভার একাধিক খুব একযোগে অনুরোধগুলি পরিচালনা করতে পারে কিনা তা পরীক্ষা করা যেমন দরকারী useful আপনি লিনাক্স, ম্যাক বা উইন্ডোতে "&& "এর সাথে এটি ব্যবহার করতে পারেন:

   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

উবুন্টু, লিনাক্স এবং উইন্ডোজ বাইনারিগুলি পৃষ্ঠায় লিঙ্কগুলির মাধ্যমে উপলব্ধ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.