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))
এটি অধীনে কাজ করে বাশ, ksh এবং অন্যান্য আধুনিক শাঁস, তবে আপনাকে ব্যবহার করতে হবে:
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() {
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 () {
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
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