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