166

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
8
  • 3
    Can I ask why you want to sleep for 1ms? Jan 15 '13 at 14:03
  • 2
    Yes of course , in my bash script I add "sleep 1" , in some lines , but script run very slowly , so after some conclusion I calculate that sleep 0.1 also bring good results and more faster About the delay , I need delay in order to solve the ssh problem in my bash script , I perform paralel ssh login to some machines by expect and without delay its will not work , As you know from my question the delay should fit both Linux and Solaris
    – yael
    Jan 15 '13 at 14:09
  • 5
    Whatever solution you choose, keep in mind that a shell script won't be very accurate in terms of timing.
    – scai
    Jan 15 '13 at 14:34
  • How about doing something that takes a very short time to execute, but does nothing.. like echo "" >/dev/null Jan 15 '13 at 15:01
  • Good idea but how msec this command take? , I need 0.1 msec , not less then that -:)
    – yael
    Jan 15 '13 at 15:12
81

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
3
  • 2
    Ah, since you're using expect you can probably just use "after N", where N is milliseconds, directly in your script. Jan 15 '13 at 14:46
  • use usleep like @Luis Vazquez and @sebix write
    – Ilan.K
    Feb 20 '16 at 9:36
  • Apple MacOS has BSD sleep, which also supports fractional seconds
    – roblogic
    Aug 26 '19 at 3:10
161

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.

7
  • 1
    see my remark about SOLARIS OS
    – yael
    Jan 15 '13 at 13:37
  • Did you mix up is and isn't?
    – scai
    Jan 15 '13 at 13:42
  • see my update in my quastion
    – yael
    Jan 15 '13 at 13:45
  • 1
    Yael, I think there're still one too many negatives in your question; are you sure you mean "not illegal syntax"?
    – MadHatter
    Jan 15 '13 at 14:23
  • 1
    Note: The built-in Bash command sleep is different from the external / separate binary sleep, which is usually installed in /bin/sleep or /usr/bin/sleep. By default, Bash will use the built-in, so use "$(which sleep)" to be very clear about using external binary.
    – kevinarpe
    Mar 23 '15 at 11:23
74

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
4
  • 4
    You can also drop the leading zero before the decimal point. eg. sleep .5 Jun 22 '14 at 7:13
  • 2
    Except for mathforum.org/library/drmath/view/52352.html
    – stark
    Oct 27 '17 at 13:42
  • Talk about everyone else overcomplicating it...
    – Martin
    Sep 5 '18 at 7:45
  • 2
    @MikeCauser leading zeros much more readable and signal intent to the reader of the code later. also better when you actually do math. Dec 22 '18 at 6:51
13

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.

12

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

usleep 1000
3
  • 2
    $ usleep No command 'usleep' found, did you mean: Command 'sleep' from package 'coreutils' (main) usleep: command not found Apr 5 '17 at 14:18
  • No, i mean usleep part of the initscripts package which is standard at least in all the Red Hat derived distributions; including at least RHEL, CentOS, Fedora, Mageia/Mandriva and SuSE. Here an example: `` `` Jul 15 '17 at 17:14
  • 1
    Here is a sample ilustration running in CentOS 7: ``` $ which usleep /usr/bin/usleep $ rpm -qf /usr/bin/usleep initscripts-9.49.37-1.el7_3.1.x86_64 ``` To summarize: - sleep (from coreutils) works with seconds - usleep (from initscripts) works with micro-seconds Jul 15 '17 at 17:22
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.

5
  • 1
    You could at least change that bare usleep() call to if(argc == 1) { usleep(atoi(argv[1])); } to avoid indexing outside of the bounds of the array, which can lead to any number of unexpected behaviors.
    – user
    Oct 13 '16 at 15:05
  • @aCVn It's actually if (argc == 2) { usleep(atoi(argv[1])); } ... Mar 25 '19 at 23:42
  • Also note that usleep unit is μs, so to wait 1 second, you need to provide a 1000000 argument. Mar 25 '19 at 23:45
  • @RingØ Right. Stupid mistake, good catch.
    – user
    Mar 26 '19 at 7:57
  • atoi() is a horrible choice to convert a string to an int. What does atoi( "STRING" ) return? atoi() has no way to return any error. Mar 26 '19 at 13:18
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/.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.