මෑත ලිනක්ස් කර්නලය යටතේ මෑත බැෂ්> = 4.2 පදනම් කරගත් පිළිතුර.
ක්රියාත්මක කිරීමේ කාලය සීමා කිරීම සඳහා, දෙබලක නැත ! බිල්ට්-ඉන් පමණක් භාවිතා වේ.
මේ සඳහා, මම read
වෙනුවට බිල්ඩින් ශ්රිතය භාවිතා කරමි sleep
. අවාසනාවට මෙය නොටි සැසි සමඟ ක්රියා නොකරනු ඇත.
ඉල්ලූ පරිදි ඉක්මන් බැෂ් ශ්රිතය " repeat
":
repeat () {
local repeat_times=$1 repeat_delay=$2 repeat_foo repeat_sleep
read -t .0001 repeat_foo
if [ $? = 1 ] ;then
repeat_sleep() { sleep $1 ;}
else
repeat_sleep() { read -t $1 repeat_foo; }
fi
shift 2
while ((repeat_times)); do
((repeat_times=repeat_times>0?repeat_times-1:repeat_times))
"${@}"
((repeat_times))&& ((10#${repeat_delay//.})) &&
repeat_sleep $repeat_delay
done
}
උපුටා ගත් නූල් සහිත කුඩා පරීක්ෂණය:
repeat 3 0 printf "Now: %(%T)T, Hello %s.\n" -1 Guy
Now: 15:13:43, Hello Guy.
Now: 15:13:43, Hello Guy.
Now: 15:13:43, Hello Guy.
repeat -1 .5 printf "Now: %(%T)T, Hello %s.\n" -1 Guy
Now: 15:14:14, Hello Guy.
Now: 15:14:14, Hello Guy.
Now: 15:14:15, Hello Guy.
Now: 15:14:15, Hello Guy.
Now: 15:14:16, Hello Guy.
Now: 15:14:16, Hello Guy.
Now: 15:14:17, Hello Guy.
Now: 15:14:17, Hello Guy.
Now: 15:14:18, Hello Guy.
Now: 15:14:18, Hello Guy.
^C
ඉදිරිපත් කරන ලද විධානයෙහි කැටිතිභාවය හා කාලසීමාව අනුව ...
මෑත කාලීන ලිනක්ස් කර්නල් යටතේ, /proc/timer_list
නැනෝ තත්පරවල කාල තොරතුරු අඩංගු ප්රකාශනයක් ඇත.
ඔබට තත්පරයකට වරක් විධානයක් ක්රියාත්මක කිරීමට අවශ්ය නම්, ඔබේ විධානය තත්පරයකට අඩු කාලයකින් අවසන් විය යුතුය! හා එහි සිට, ඔබට ඇති sleep
එකම ඉතිරි වත්මන් දෙවන.
ප්රමාදය වඩා වැදගත් නම් සහ ඔබේ විධානයට සැලකිය යුතු කාලයක් අවශ්ය නොවේ නම්, ඔබට:
command=(echo 'Hello world.')
delay=10
while :;do
printf -v now "%(%s)T" -1
read -t $(( delay-(now%delay) )) foo
${command[@]}
done.
නමුත් ඔබේ ඉලක්කය වඩාත් සියුම් කැටි ගැසීමක් ලබා ගැනීමට නම්, ඔබ කළ යුත්තේ:
තත්පරයක් ආරම්භ වන තෙක් බලා සිටීමට නැනෝ තත්පර තොරතුරු භාවිතා කරන්න ...
මේ සඳහා, මම කුඩා බැෂ් ශ්රිතයක් ලිවීය:
# bash source file for nano wait-until-next-second
mapfile </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
((_c+=${#_timer_list[_i]}))
[[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_READ=$_c
[[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
break
done
unset _i _timer_list _c
readonly TIMER_LIST_OFFSET TIMER_LIST_READ
waitNextSecondHires() {
local nsnow nsslp
read -N$TIMER_LIST_READ nsnow </proc/timer_list
nsnow=${nsnow%% nsecs*}
nsnow=$((${nsnow##* }+TIMER_LIST_OFFSET))
nsslp=$((2000000000-10#${nsnow:${#nsnow}-9}))
read -t .${nsslp:1} foo
}
ඒවා උපුටා ගැනීමෙන් පසු, ඔබට:
command=(echo 'Hello world.')
while :;do
waitNextSecondHires
${command[@]}
done.
${command[@]}
සැසඳීමට වඩා විධාන රේඛාවේ කෙලින්ම ධාවනය කරන්න
command=(eval "echo 'Hello world.';sleep .3")
while :;do
waitNextSecondHires
${command[@]}
done.
මෙය හරියටම එකම ප්රති .ලයක් ලබා දිය යුතුය.
ඉල්ලූ පරිදි bash ශ්රිතය කුලියට repeat
ගනී:
ඔබට මෙය මූලාශ්ර කළ හැකිය:
mapfile </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
((_c+=${#_timer_list[_i]}))
[[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_READ=$_c
[[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
break
done
unset _i _timer_list _c
readonly TIMER_LIST_OFFSET TIMER_LIST_READ
repeat_hires () {
local repeat_times=$1 repeat_delay=$2 repeat_foo repeat_sleep repeat_count
read -t .0001 repeat_foo
if [ $? = 1 ] ;then
repeat_sleep() { sleep $1 ;}
else
repeat_sleep() { read -t $1 repeat_foo; }
fi
shift 2
printf -v repeat_delay "%.9f" $repeat_delay
repeat_delay=${repeat_delay//.}
read -N$TIMER_LIST_READ nsnow </proc/timer_list
nsnow=${nsnow%% nsec*}
started=${nsnow##* }
while ((repeat_times)); do
((repeat_times=repeat_times>0?repeat_times-1:repeat_times))
"${@}"
((repeat_times)) && ((10#$repeat_delay)) && {
read -N$TIMER_LIST_READ nsnow </proc/timer_list
nsnow=${nsnow%% nsec*}
nsnow=${nsnow##* }
(( (nsnow - started) / 10#$repeat_delay - repeat_count++ )) &&
printf >&2 "WARNING: Command '%s' too long for %f delay.\n" \
"${*}" ${repeat_delay:0:${#repeat_delay}-9
}.${repeat_delay:${#repeat_delay}-9}
printf -v sleep "%010d" $((
10#$repeat_delay - ( ( nsnow - started ) % 10#$repeat_delay ) ))
repeat_sleep ${sleep:0:${#sleep}-9}.${sleep:${#sleep}-9}
}
done
}
ඉන්පසු එය උත්සාහ කරන්න:
time repeat_hires 21 .05 sh -c 'date +%s.%N;sleep .01'
1480867565.152022457
1480867565.201249108
1480867565.251333284
1480867565.301224905
1480867565.351236725
1480867565.400930482
1480867565.451207075
1480867565.501212329
1480867565.550927738
1480867565.601199721
1480867565.651500618
1480867565.700889792
1480867565.750963074
1480867565.800987954
1480867565.853671458
1480867565.901232296
1480867565.951171898
1480867566.000917199
1480867566.050942638
1480867566.101171249
1480867566.150913407
real 0m1.013s
user 0m0.000s
sys 0m0.016s
time repeat_hires 3 .05 sh -c 'date +%s.%N;sleep .05'
1480867635.380561067
WARNING: Command 'sh -c date +%s.%N;sleep .05' too long for 0.050000 delay.
1480867635.486503367
WARNING: Command 'sh -c date +%s.%N;sleep .05' too long for 0.050000 delay.
1480867635.582332617
real 0m0.257s
user 0m0.000s
sys 0m0.004s