Search code examples
shellrandomposixsleepsh

How to sleep a random fraction of a second in POSIX shell?


The following won't work:

/bin/sleep $(printf ".%02ds" $(( $RANDOM % 100 )))
  1. POSIX sleep supports only integral seconds
  2. there is no $RANDOM

I could emulate random by:

RAND255=$(od -An -N1 -t u1 /dev/urandom)

Another option is to write a small C program that utilizes usleep() and *rand*() as suggested by @dmckee and @Keith Thompson. Deploying such program might not be always possible.

Is there a better way i.e., is there an alternative for sleep in POSIX that accept fractions of a second other than a hand-written C program and is there a better way to emulate $RANDOM other than od?


Solution

  • In your first command, if $RANDOM % 100 is 6, for example, it will invoke /bin/sleep .6s; you want /bin/sleep .06s.

    In the second command, od -An -N1 -t u1 /dev/random seems to print a number in the range 0..255 -- and the command itself can delay for a long time if /dev/random runs out of entropy. Use /dev/urandom instead.

    I'd write a small C program that calls usleep() (assuming that compiling it and deploying the executable is feasible).

    EDIT:

    As far as I can tell, the answer to your (updated) question is no.

    POSIX doesn't guarantee /dev/urandom, so your od command isn't portable to all POSIX systems. I don't believe POSIX specifies any command that can sleep for fractional seconds. It does specify the nanosleep() function, but if you can't necessarily deploy a C program that doesn't help. POSIX awk has no sleep function. Perl is not POSIX.

    Your options are: (1) sleep only for whole seconds, or (2) use a non-portable method.

    What environment(s) do you need this for?