With a "normal" (I mean full) Linux distro, it works just fine:

sleep $(echo "$[ ($RANDOM % 10 ) ]")

OK, it waits for about 0-9 seconds.

but under OpenWRT [not using bash, but rather ash]:

$ sleep $(echo "$[ ($RANDOM % 9 ) ]")
sleep: invalid number '$['

and why:

$ echo "$[ ($RANDOM % 9 ) ]"
$[ ( % 9 ) ]

So does anyone have a way to generate random numbers under OpenWRT, so I can put it into the "sleep"?

  • ash isn't bash; you can't use bash features with it. Jan 13, 2011 at 0:10
  • @user62367 someone from SO has already answer your question.
    – greatwolf
    Jan 13, 2011 at 11:52
  • 1
    Seriously, stop crossposting.
    – Wuffers
    Feb 5, 2011 at 15:41

3 Answers 3


Ash doesn't understand $[] and it's deprecated in Bash. Also, the echo is unnecessary. Use this instead for both Bash and Ash:

sleep $(( $RANDOM % 10 ))

Also consider that Busybox included in OpenWrt does not usually have the $RANDOM compiled in.

You can have it if at compilation time you select the BUSYBOX_CUSTOM and BUSYBOX_CONFIG_ASH_RANDOM_SUPPORT configuration options in the OpenWrt buildroot.

Otherwise, you can use a command like this:

hexdump -n 2 -e \"%u\" /dev/urandom

That generates a number between 0 and 65535. So, if you want to run sleep for 0-9 seconds you can do something like:

sleep $(($(hexdump -n 2 -e \"%u\" /dev/urandom) % 10))

where the $((... % 10)) part is needed for reducing the 0-65535 space to 0-9.


Here's an (unreliable) way to produce an integer between 0 and 9 (inclusive):

sleep $(head -30 /dev/urandom | tr -dc "0123456789" | head -c1)

This reads 30 lines from /dev/urandom, uses tr to discard all characters that aren't digits, and then grabs only the first character of the remaining digits.  This is unreliable insofar as there is a possibility (with very low probability) that /dev/urandom will yield 30 lines that happen to contain no digits.

This can be extended to generate a three-digit number (in the range 0-999) as follows:

$(head -30 /dev/urandom | tr -dc "0123456789" | head -c3)
  • "This is unreliable insofar as there is a possibility …" – True. What do you need the first head for in the first place? Use </dev/urandom tr -dc "0123456789" | head -c1. If you are unfortunate then the command will take some time (it will read and discard many bytes from /dev/urandom). There is no upper bound for duration time, but the probability the command never finishes is 0. This means you just need to wait as much as it takes to get one digit for sure. In this sense my command is reliable. Getting more digits (like with head -c3) is equally reliable, it may just take more time. Mar 14 at 16:36

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.