1. Overview

We may need to generate random integer numbers within a specific range for several reasons while writing Bash scripts. For example, we may need to generate a random TCP/UDP port number between 1024 and 65535 for user applications.

In this tutorial, we’ll discuss several methods to generate random numbers within a specific range in Bash. The ranges we’ll use will be inclusive, i.e., the lower and upper bounds of the range are included in the range.

2. Using $RANDOM

One option for generating random numbers within a range is using the built-in $RANDOM environment variable. Each time we use this environment variable, a random integer number between 0 and 32767 is generated:

$ echo $RANDOM $RANDOM $RANDOM
6104 25795 16292

We called $RANDOM three times in a single echo command. The generated numbers were 6104, 25795 and 16292.

Although calling $RANDOM generates an integer number between 0 and 32767 by default, it’s possible to generate a random number in a specific range.

Let’s use $RANDOM to generate a random number between 10 and 20 as an example:

$ min=10
$ max=20 
$ echo $(($RANDOM%($max-$min+1)+$min))
20
$ echo $(($RANDOM%($max-$min+1)+$min))
14

($max-$min+1) is 11 in our example. Therefore, $RANDOM%($max-$min+1) part of the expression generates a random integer number between 0 and 10. % is the modulo operator in Bash. Finally, adding $min to $RANDOM%($max-$min+1) results in an integer number between 10 and 20.

3. Using shuf

Another option for generating random numbers within a specific range is using the shuf command:

$ shuf –i $min-$max –n 1
12

The generated random integer number is 12 in the above example, where the values of $min and $max are 10 and 20 as before.

The -i option of shuf specifies the input range. The generated numbers are randomly selected from the specified range. The -n option specifies the number of random numbers that must be generated by shuf. In our example, shuf produces only one random number because we pass -n 1 to shuf.

4. Using awk

We can also use awk for generating random numbers in a specific range:

$ awk "BEGIN{srand(); print int(rand()*($max-$min+1))+$min}"
20

We generate the random number in the BEGIN rule of awk since we don’t provide any input file to awk. This rule is executed only once.

We must call the srand() function of awk to initialize the seed for random number generation. *If we don’t pass any arguments to srand(), awk uses the current date and time of day for the seed*.

The rand() function of awk generates a random number between 0 and 1. The int() function of awk, on the other hand, returns the integer part of a real number. Therefore, the expression int(rand()*($max-$min+1))+$min in double parentheses generates a random number between $min and $max.

We can use other seeds while using awk, for example $RANDOM:

$ awk -v seed=$RANDOM "BEGIN{srand(seed); print int(rand()*($max-$min+1))+$min}"
13

The -v option of awk is for assigning a value to a variable before the execution of awk begins. The -v seed=$RANDOM in our example defines the variable seed having the value $RANDOM. Therefore, calling srand(seed) in the BEGIN rule initializes the seed with the value obtained from the $RANDOM environment variable.

5. Using od

We can use the od command together with the kernel random number source devices to generate random numbers.

Let’s use od with /dev/urandom:

$ od -An -N2 -d /dev/urandom
41803

The /dev/urandom device file is the kernel random number source device. It’s non-blocking, so it generates random data continuously. Another option is the /dev/random device file. It may block when it runs out of entropy.

The -An option of od prints the result with no offset information. The -N2 option reads two bytes of input. Finally, the -d option of od displays the result as a two-byte unsigned integer number.

Unfortunately, it isn’t possible to specify a range while using the od command. However, we can call od inside an infinite while loop until we obtain a number in the desired range. We’ll use the following script, get_random_number.sh, for this purpose:

#!/bin/bash

min=10
max=20

while true
do
    odn=$(od -An -N1 -d /dev/urandom)

    if [[ $odn -ge $min ]] && [[ $odn -le $max ]]
    then
        echo $odn
        break
    fi
done

The while loop is an infinite loop since the condition of the loop is always true. We assign the random number obtained from od to the variable odn using odn=$(od -An -N1 -d /dev/urandom). We read one byte from the input as our range is between 10 and 20.

If the random number is within the range, i.e., between $min and $max, we print it using echo $odn. Then, we exit from the while loop using break. If the random number is outside the range, we continue generating a random number using od.

Let’s run the script:

$ ./get_random_number.sh
17

The random number we obtained is 17, which is within the range 10 and 20, as expected.

The performance of this solution may not be good in the case of a small range with big range boundaries, for example, within the range 20000 and 20050 because of the number of trials and misses.

6. Using Python

We can use the Python programming language for generating random numbers within a specific range.

It’s possible to execute Python statements from the command line without writing Python scripts using the -c option of the python command:

$ python –c "import random; print(random.randint($min,$max))"
14

The first statement in the double quotes, import random, imports the random module, which is a pseudo-random number generator for various distributions.

Then, we call the randint() function of the random module. This function produces a random integer number within the range specified by its first and second parameters. We specify the range using the environment variables $min and $max. Finally, we print the returned number from random.randint() using the print() function of Python.

7. Using Perl

Perl is another programming language that we can use for generating random numbers within a specific range.

Like Python, we can execute Perl statements from the command line without writing Perl scripts:

$ perl –e "print int(rand($max-$min+1)) + $min"
19

The -e option of the perl command is like the -c option of python. It lets us execute Perl statements from the command line.

The rand() function in Perl returns a random real number. The int() function converts the real number passed to it to an integer number.

For example, int(rand(10)) returns a random integer number between 0 and 9. Therefore, the int(rand($max-$min+1)) part of the expression in double parentheses passed to the perl command returns a random integer number between 0 and 10. Adding the $min value results in a random number in the range 10 and 20.

8. Conclusion

In this article, we discussed how to generate random integer numbers within a specific range.

We saw that we can use the built-in $RANDOM environment variable. Then, we discussed the shuf, awk, and od commands.

Finally, we learned that it’s possible to use the Python and Perl programming languages from the command line to generate numbers in a specific range.