Featured, FreeBSD, Linux, Mac OS X, Technical

HOWTO: Random Number in Shell Script

The other day I was working on a shell script to be run on several hundred machines at the same time. Since the script was going to download a file from a central server, and I did not want to overwhelm the central server with hundreds of simultaneous requests, I decided that I wanted to add a random wait time. But how do you conjure a random number within a specific range in a shell script?

Updated: Due to much feedback, I now know of three ways to do this . . .

1) On BSD systems, you can use jot(1):
sleep `jot -r 1 1 900`

2) If you are scripting with bash, you can use $RANDOM:
sleep `echo $RANDOM%900 | bc`

3) For portability, you can resort to my first solution:
# Sleep up to fifteen minutes
sleep `echo $$%900 | bc`

$$ is the process ID (PID), or “random seed” which on most systems is a value between 1 and 65,535. Fifteen minutes is 900 seconds. % is modulo, which is like division but it gives you the remainder. Thus, $$ % 900 will give you a result between 0 and 899. With bash, $RANDOM provides the same utility, except it is a different value whenever you reference it.

Updated yet again . . . says a friend:
nah it’s using `echo .. | bc` that bugs me, 2 fork+execs, let your shell do the math, it knows how
so $(( $$ % 900 )) should work in bsd sh

For efficiency, you could rewrite the latter two solutions:
2.1) sleep $(( $RANDOM % 900 ))
3.1) sleep $(( $$ % 900 ))

The revised solution will work in sh-derived shells: sh, bash, ksh. My original “portable” solution will also work if you’re scripting in csh or tcsh.

Read More

Categories: Featured, FreeBSD, Linux, Mac OS X, Technical

  • Me

    sleep `/usr/bin/jot -r 1 1 1200`

  • Note that the bash random number generator uses the pretty crappy rand() algorithm to generate pseudorandom numbers.  It also generates a signed 16 bit number, so the max value it generates is 32767.

    I much prefer using perl to generate random numbers, as it uses a better random number algorithm and it creates arbitrarily large random numbers.  For example:

    $ perl -e ‘print int rand(10000000000000000000); print “n”‘