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.
Responses
Me
sleep `/usr/bin/jot -r 1 1 1200`phrenologist
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”‘
8492917251578582016
Comment
Tiny Print:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>