Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash command wait until next full second

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 ;)

like image 912
Search898 Avatar asked Oct 20 '25 09:10

Search898


2 Answers

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.

like image 188
Peter Cordes Avatar answered Oct 21 '25 23:10

Peter Cordes


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

like image 24
sleeplessnerd Avatar answered Oct 21 '25 23:10

sleeplessnerd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!