190

sleep is a very popular command and we can start sleep from 1 second:

# wait one second please 
sleep 1

but what the alternative if I need to wait only 0.1 second or between 0.1 to 1 second ?

  • remark: on linux or OS X sleep 0.XXX works fine , but on solaris sleep 0.1 or sleep 0.01 - illegal syntax
yael
  • 2,563

8 Answers8

178

The documentation for the sleep command from coreutils says:

Historical implementations of sleep have required that number be an integer, and only accepted a single argument without a suffix. However, GNU sleep accepts arbitrary floating point numbers. See Floating point.

Hence you can use sleep 0.1, sleep 1.0e-1 and similar arguments.

scai
  • 2,359
86

Bash has a "loadable" sleep which supports fractional seconds, and eliminates overheads of an external command:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

Then:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

The downside is that the loadables may not be provided with your bash binary, so you would need to compile them yourself as shown (though on Solaris it would not necessarily be as simple as above).

As of bash-4.4 (September 2016) all the loadables are now built and installed by default on platforms that support it, though they are built as separate shared-object files, and without a .so suffix. Unless your distro/OS has done something creative (sadly RHEL/CentOS 8 build bash-4.4 with loadable extensions deliberately removed), you should be able to do instead:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(The man page implies BASH_LOADABLES_PATH is set automatically, I find this is not the case in the official distribution as of 4.4.12. If and when it is set correctly you need only enable -f filename commandname as required.)

If that's not suitable, the next easiest thing to do is build or obtain sleep from GNU coreutils, this supports the required feature. The POSIX sleep command is minimal, older Solaris versions implemented only that. Solaris 11 sleep does support fractional seconds.

As a last resort you could use perl (or any other scripting that you have to hand) with the caveat that initialising the interpreter may be comparable to the intended sleep time:

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh
mr.spuratic
  • 3,570
82

Sleep accepts decimal numbers so you can break it down this like:

1/2 of a second

 sleep 0.5

1/100 of a second

sleep 0.01

So for a millisecond you would want

sleep 0.001
14

Try this to determine accuracy:

    time sleep 0.5      # 500 milliseconds (1/2 of a second)
    time sleep 0.001    # 1 millisecond (1/1000 of a second)
    time sleep 1.0      # 1 second (1000 milliseconds)

Combination of mr.spuratic's solution and coles's solution.

dsrdakota
  • 241
13

You may simply use usleep. It takes microseconds (= 1e-6 seconds) as parameter, so to sleep 1 millisecond you would enter:

usleep 1000
sebix
  • 4,432
5

I had the same problem (no shell usleep on Solaris) so I wrote my own thus:

  #include "stdio.h"
  int main(int argc, char **argv) {
     if(argc == 2) { usleep(atoi(argv[1])); }
     return 0;
}

Doesn't check arguments - I'd recommend a properly written one if you wanted to keep it but that (gcc usleep.c -o usleep) will get you out of a hole.

Déjà vu
  • 5,778
0

The POSIX specification for sleep only accepts an integral argument -- so no fractions of a second. GNU's coreutils sleep adds support for real numbers, suffixes, even scientific notation and infinity as GNU extensions. But if you're on embedded system with busybox or just don't have coreutils, then you're out of luck unless you have perl.

perl -e 'select(undef, undef, undef, 0.1);'
0

I like the usleep idea, but I can't make a comment under it. Since this helped me out, I hope my suggestion can improve the usleep idea.

https://github.com/fedora-sysv/initscripts/blob/3c3fe4a4d1b2a1113ed302df3ac9866ded51b01b/src/usleep.c is the actual source code for usleep.c on the redhat ecosystem.

Try to compile that in your Solaris. You'd probably need https://www.opencsw.org/packages/libpopt0/.

edzzz
  • 11