I'm asking for how to wait for the nextfull second? I dont mean sleep 1! For example we have the time 07:45:06.729. The last 729 means the milliseconds. So how we can i say wait until next full second? It would be 07:45:07.000
Thanks ;)
This is like Matt's answer, but doesn't have a busy-wait to try to wake up early. This simplifies things a lot, because we never have to care about anything but the fractional-second part of the current time.
Use GNU date +%N
to get the nanoseconds portion of the current time, and sleep
for 1 - that.
sleep_to_next_second(){
#TODO: check for 0000 and don't sleep at all, instead of for 0.10000
sleep 0.$(printf '%04d' $((10000 - 10#$(date +%4N))))
}
(FIXME: to fix the special-case bug, you'd just do a text compare for 0000. If so, you're already at the start of a second; don't sleep. So capture the printf result into a local duration=$(...)
variable, or printf -v duration
to print into a variable.)
The tricks are:
numbers with leading zeros are treated as octal in a bash arithmetic context, so use 10#$date
to force base10.
Since bash can only do integer math, the obvious thing is to use fixed-point thousandths of a second or something, and tack on a leading decimal point. This makes leading zeros essential, so that you sleep for 0.092 seconds, not 0.92. I used printf '%04d'
to format my numbers.
experimental testing:
# echo instead of sleep to see what numbers we generate
while true;do echo 0.$(printf '%04d' $((10000 - 10#$(date +%4N))));done
...
0.0049
0.0035
0.0015
0.10000 ##### minor bug: sleeps for 0.1 sec if the time was bang-on a ten-thousandth
0.9987
0.9973
0.9960
while true;do date +"%s %N"; sleep 0.$(printf '%04d' $((10000 - 10#$(date +%4N))));done
1445301422 583340443
1445301423 003697512
1445301424 003506054
1445301425 003266620
1445301426 003776955
1445301427 003921242
1445301428 003018890
1445301429 002652820
# So typical accuracy is 0.003 secs after the rollover to the next second, on a near-idle desktop
Ubuntu 15.04: GNU bash/date/sleep on Linux 3.19 on Intel i5-2500k, idling at 1.6GHz, turbo 3.8GHz.
The GNU sleep command accepts floating point parameters. So you could calculate the exact time to wait and call sleep with the result.
See https://superuser.com/questions/222301/unix-sleep-until-the-specified-time
and https://serverfault.com/questions/469247/how-do-i-sleep-for-a-millisecond-in-bash-or-ksh
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With