How to generate a random number within a range in Bash?
-
35How random does it need to be? – bdonlan Jul 28 '09 at 16:03
26 Answers
Use $RANDOM
. It's often useful in combination with simple shell arithmetic. For instance, to generate a random number between 1 and 10 (inclusive):
$ echo $((1 + $RANDOM % 10))
3
The actual generator is in variables.c
, the function brand()
. Older versions were a simple linear generator. Version 4.0 of bash
uses a generator with a citation to a 1985 paper, which presumably means it's a decent source of pseudorandom numbers. I wouldn't use it for a simulation (and certainly not for crypto), but it's probably adequate for basic scripting tasks.
If you're doing something that requires serious random numbers you can use /dev/random
or /dev/urandom
if they're available:
$ dd if=/dev/urandom count=4 bs=1 | od -t d
-
47Be careful here. While this is fine in a pinch, doing arithmetic on random numbers can dramatically affect the randomness of your result. in the case of `$RANDOM % 10`, 8 and 9 are measurably (though marginally) less probable than 0-7, even if `$RANDOM` is a robust source of random data. – dimo414 Feb 22 '14 at 22:51
-
9@dimo414 I'm curious to "marginally", do you have a source where I can find out more about this? – PascalVKooten May 26 '14 at 06:27
-
118By moduloing your random input, you are "[pigeon-holing](http://en.wikipedia.org/wiki/Pigeonhole_principle)" the results. Since `$RANDOM`'s range is `0-32767` the numbers `0`-`7` map to `3277` different possible inputs, but `8` and `9` can only be produced `3276` different ways (because `32768` and `32769` aren't possible). This is a minor issue for quick hacks, but means the result is not uniformly random. Random libraries, like Java's `Random`, offer functions to properly return a uniform random number in the given range, rather than simply mod-ing a non-divisible number. – dimo414 May 26 '14 at 16:07
-
@dimo414: depending on PRNG, applying `% n` may be even worse. Look at the last picture in [Test PRNG using gray bitmap](https://www.wakari.io/sharing/bundle/jfs/Test%20PRNG%20using%20gray%20bitmap). It shows the obvious skew – jfs Sep 24 '14 at 07:29
-
1@J.F.Sebastian very true - the problem with modulo is it can break the uniformity of *any* RNG, not just bad PRNGs, but thanks for calling this out. – dimo414 Sep 24 '14 at 13:41
-
43Just for context, the basic pigeonholing for % 10 means 8 and 9 are about .03% less likely to occur than 0–7. If your shell script requires more accurate uniform random numbers than that, then by all means use a more complex and proper mechanism. – Nelson Sep 24 '14 at 23:48
-
On my mac, I had to use `echo $((1 + $RANDOM % 10))` with the `$RANDOM`, not just `RANDOM`. – nomadic_squirrel Mar 26 '19 at 18:35
-
1$RANDOM has some weird properties in zsh: Try: `echo $RANDOM; echo $RANDOM`. Now try `(echo $RANDOM); (echo $RANDOM)`. The former gives two different numbers, the latter does not. Using `shuf` avoids this problem. I think that shuf is the better solution. – Eyal Feb 28 '20 at 15:38
-
1@Eyal According to the docs, the same sequence is repeated by each shell, by design. You can manually seed the generator and also have subshells share a sequence. http://zsh.sourceforge.net/Doc/Release/Parameters.html#index-RANDOM – remcycles May 23 '20 at 14:45
-
You need entropy. See https://stackoverflow.com/a/65207245/1208218 – Roel Van de Paar Dec 08 '20 at 21:39
-
10In `(())`, you can skip the prefix `$` of variable, like this `$((1 + RANDOM % 10))`. – LianSheng Dec 29 '20 at 17:18
-
this always retrun 0 for me when I run my script with `sh` and not `bash`. Why is that? – Charlie Parker Jul 19 '21 at 21:02
-
@CharlieParker, I believe the [arithmetic expansion (`$(( ))`)](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Arithmetic-Expansion) is a bash-only thing that is not supported by `sh`. I don't write scripts in `sh`. I find it much more difficult. `bash` seems to me to be much more powerful. – Gabriel Staples Mar 07 '22 at 15:09
-
I like to see source info. I found it: from `man bash`: `RANDOM Each time this parameter is referenced, a random integer between 0 and 32767 is generated. The sequence of random numbers may be initialized by assigning a value to RANDOM. If RANDOM is unset, it loses its special properties, even if it is subsequently reset.` – Gabriel Staples Mar 07 '22 at 20:33
Please see $RANDOM
:
$RANDOM
is an internal Bash function (not a constant) that returns a pseudorandom integer in the range 0 - 32767. It should not be used to generate an encryption key.

- 344,730
- 71
- 640
- 635
-
3
-
34@JinKwon `32767` is `2^16 / 2 - 1` which is the upper limit for a signed 16 bit integer. – Jeffrey Martinez Aug 03 '17 at 15:57
-
4@JinKwon could you clarify why don't you say it is `2^15 - 1`? It's equivalent, so I'm just curious if there is some context I'm missing? – Brett Holman Aug 28 '18 at 19:46
-
22@BrettHolman I think he was trying to point out the "signed" part of the signed 16 bit integer. 2^16 values, split in half for postive & negative ints. – cody Dec 19 '18 at 14:51
-
this always retrun 0 for me when I run my script with `sh` and not `bash`. Why is that? – Charlie Parker Jul 19 '21 at 21:02
-
2
-
@Sidney thats the range of a 16 bit signed integer, but `bash` apparently isnt using the full range. – sherrellbc Dec 16 '22 at 20:33
You can also use shuf
(available in coreutils).
shuf -i 1-100000 -n 1

- 32,039
- 22
- 142
- 171

- 1,338
- 1
- 9
- 10
-
How do you pass in vars as range end? I got this: `shuf -i 1-10 -n 1: syntax error in expression (error token is "1-10 -n 1")` – dat tutbrus Jul 16 '18 at 13:14
-
1Add a `$var` instead of the range end, like this: `var=100 && shuf -i 1-${var} -n 1` – knipwim Jul 17 '18 at 04:01
-
2I prefer this option as it's easy to generate N random numbers with `-n`. E.g. *Generate 5 random numbers between 1 and 100*: `shuf -i 1-100 -n 5` – aerijman Jan 14 '20 at 17:47
-
5As far as I understand the numbers are not random. If you specify `shuf -i 1-10 -n 10` you will get all numbers from 1 to 10 exactl one. If you specify `-n 15` you will still get only those 10 numbers exactly once. That is really only shuffling, not generating random numbers. – radlan Apr 27 '20 at 13:00
-
3
-
-
2By default, `shuf` doesn't use a cryptographically secure pseudo-random number generator, but it's possible to use `shuf` with `/dev/urandom` (`--random-source` option). Related: https://unix.stackexchange.com/a/705633/133353 (*By default these commands use an internal pseudo-random generator initialized*...) – Artfaith Jun 10 '22 at 04:49
Try this from your shell:
$ od -A n -t d -N 1 /dev/urandom
Here, -t d
specifies that the output format should be signed decimal; -N 1
says to read one byte from /dev/urandom
.
-
4
-
13
-
While a great answer for a source of random numbers, one should stress the point that signed decimals from 1 (or more) bytes have the caveat that, like `$RANDOM`, do not end at multiple of 10, and that may skew things if one uses the modulo. So with 1 byte one has up to 255 and thus using, say, %10, would give some digits a bit higher probabilities than others. Same with 2 bytes, 3 and so on. – Pier A Oct 15 '22 at 22:07
you can also get random number from awk
awk 'BEGIN {
# seed
srand()
for (i=1;i<=1000;i++){
print int(1 + rand() * 100)
}
}'

- 327,991
- 56
- 259
- 343
-
1+1 you know, at first I though why would you ever want to do it like this, but actually I quite like it. – zelanix Jan 29 '14 at 02:34
-
2Thanks for giving a solution that include seeding. I couldn't find it anywhere! – so.very.tired Aug 23 '16 at 10:24
-
5+1 for seeding. It might be worth mentioning that `srand()` 's seed is the current CPU time. If you need to specify a specific seed, so RNG can be duplicated, use `srand(x)` where `x` is the seed. Also, quoted from GNU awk's numeric function manual, "different awk implementations use different random-number generators internally." The upshot is that if you are interested in generating statistical distribution, you should expect slight variations going from one runtime to the next on different platform (all running `awk` or `gawk`). – Cbhihe Feb 24 '19 at 12:51
-
**BEWARE** `srand()` seeds using the current CPU time in **seconds**, so if you run this script several times in one second, the script will print the same values each time. If you want to be safe then just replace `srand()` with `srand('$(date +%s%N)')` in the answer above to use the current time in nanoseconds (this does not work on macos at time of writing but should work on Linux) – Brandon Oct 09 '22 at 22:23
I like this trick:
echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99
...

- 757
- 6
- 10
-
20$RANDOM is in the range of 0 - 32767. You will end up with more numbers that start with 1, 2 or 3, than you will 4-9. If you're okay with an imbalanced distribution, this will work fine. – jbo5112 Aug 21 '18 at 18:40
-
2@jbo5112 you are totally right, what about display last digit ? echo ${RANDOM:0-1} for one digit, ${RANDOM:0-2} for two digit ... ? – fraff Aug 28 '18 at 09:07
-
6If you use the last digit(s), it will be rather good, but it it will include 0's and 00's. On a single digit, 0-7 will occur 0.03% more often than 8-9. On 2 digits, 0-67 will occur 0.3% more often than 68-99. If you need a random number distribution that good, hopefully you're not using bash. With the original: `${RANDOM:0:1}` has a 67.8% chance of giving you a 1 or a 2, `${RANDOM:0:2}` only has a 0.03% chance of giving you a single digit number (should be 1%), and both have a 0.003% chance of giving you a 0. There are still use cases where this is fine (e.g. non-consistent input). – jbo5112 Aug 29 '18 at 17:45
There is $RANDOM. I don't know exactly how it works. But it works. For testing, you can do :
echo $RANDOM

- 45,082
- 11
- 119
- 130

- 4,923
- 7
- 40
- 68
bash 5.1 introduces a new variable, SRANDOM
, which gets its random data from the system's entropy engine and so is not linear and cannot be reseeded to get an identical random sequence. This variable can be used as a substitute for RANDOM
for generating more random numbers.
$ echo $((1 + SRANDOM % 10))
4

- 72,056
- 11
- 123
- 141

- 1
- 16
- 47
- 69
Random number between 0 and 9 inclusive.
echo $((RANDOM%10))

- 10,639
- 3
- 49
- 62
-
2My bad, didn't read the man page properly. `$RANDOM` only goes from 0 to 32767. It should have said "Random number mostly between 1 and 3, with a few wingers" ;) – David Newcomb Dec 07 '13 at 14:00
-
4What? It'll still be between 0 and 9, though 8 and 9 will have slightly less probability of occurring than 0 through 7, as mentioned in another answer. – kini Apr 07 '16 at 07:54
I wrote several articles on this.
- https://linuxconfig.org/generating-random-numbers-in-bash-with-examples
- https://linuxconfig.org/random-entropy-in-bash
- https://www.cloudsavvyit.com/7572/how-to-generate-better-random-numbers-at-the-bash-command-line/
$ RANDOM=$(date +%s%N | cut -b10-19 | sed 's|^[0]\+||')
$ echo $(( $RANDOM % 113 + 13 ))
The above will give a number between 13 and 125 (113-1+13), with reasonable random entropy.

- 2,111
- 1
- 24
- 38
-
2I added a tweak to get rid of leading zeros: RANDOM=$(date +%s%N | cut -b10-19 | sed -e 's/^0*//;s/^$/0/') – JCCyC Jul 01 '21 at 21:28
-
1@JCCyC Interesting idea! Why remove blanks and swap with `0` though? i.e. that should not happen to start with? – Roel Van de Paar Jul 01 '21 at 23:10
-
it happened to me, the first of the last 9 digits coming from `date +%s%N` was sometimes zero and the code I fed the numbers to thought it was octal. :-O The second s command is for the rare case in which the 9 last digits are all zero, to guarantee the output will not be empty but a single "0". – JCCyC Jul 02 '21 at 09:07
-
In fact, it happens during one second every 10 seconds -- whenever the integer number of Epoch seconds ends with 0. Try this one for fun: while [ 1 ]; do echo -en `date +"%s %N"`" "`date +%s%N | cut -b10-19`"\r"; done – JCCyC Jul 02 '21 at 09:17
-
Urgh, backquote messed things up. Lemme try again. `while [ 1 ]; do echo -en $(date +"%s %N")" "$(date +%s%N | cut -b10-19)"\r"; done` – JCCyC Jul 02 '21 at 09:19
-
1@JCCyC A better option to strip the leading zero, instead of using `sed` (a separate program), is Bash's parameter expansion: `${RANDOM#0}`. – legends2k Jun 28 '23 at 08:13
-
1@legends2k That would not work, as the issue is in the `RANDOM=...` assignment. I've fixed the answer to include a `0`-fix using `sed`. – Roel Van de Paar Jun 28 '23 at 21:26
-
2@Roel You're right, I missed the point that we've to assign to `RANDOM` without the leading zero to seed the random number generator. Using another variable is an option though: [live example](https://onlinegdb.com/B1JJRkauv); an extra line but not an extra process. Thanks for the answer and the links :) – legends2k Jun 29 '23 at 15:59
-
If you are using a linux system you can get a random number out of /dev/random or /dev/urandom. Be carefull /dev/random will block if there are not enough random numbers available. If you need speed over randomness use /dev/urandom.
These "files" will be filled with random numbers generated by the operating system. It depends on the implementation of /dev/random on your system if you get true or pseudo random numbers. True random numbers are generated with help form noise gathered from device drivers like mouse, hard drive, network.
You can get random numbers from the file with dd

- 187,060
- 113
- 301
- 369
Reading from /dev/random or /dev/urandom character special files is the way to go.
These devices return truly random numbers when read and are designed to help application software choose secure keys for encryption. Such random numbers are extracted from an entropy pool that is contributed by various random events. {LDD3, Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman]
These two files are interface to kernel randomization, in particular
void get_random_bytes_arch(void* buf, int nbytes)
which draws truly random bytes from hardware if such function is by hardware implemented (usually is), or it draws from entropy pool (comprised of timings between events like mouse and keyboard interrupts and other interrupts that are registered with SA_SAMPLE_RANDOM).
dd if=/dev/urandom count=4 bs=1 | od -t d
This works, but writes unneeded output from dd
to stdout. The command below gives just the integer I need. I can even get specified number of random bits as I need by adjustment of the bitmask given to arithmetic expansion:
me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))

- 29,204
- 9
- 82
- 118
I have taken a few of these ideas and made a function that should perform quickly if lots of random numbers are required.
calling od
is expensive if you need lots of random numbers. Instead I call it once and store 1024 random numbers from /dev/urandom. When rand
is called, the last random number is returned and scaled. It is then removed from cache. When cache is empty, another 1024 random numbers is read.
Example:
rand 10; echo $RET
Returns a random number in RET between 0 and 9 inclusive.
declare -ia RANDCACHE
declare -i RET RAWRAND=$(( (1<<32)-1 ))
function rand(){ # pick a random number from 0 to N-1. Max N is 2^32
local -i N=$1
[[ ${#RANDCACHE[*]} -eq 0 ]] && { RANDCACHE=( $(od -An -tu4 -N1024 /dev/urandom) ); } # refill cache
RET=$(( (RANDCACHE[-1]*N+1)/RAWRAND )) # pull last random number and scale
unset RANDCACHE[${#RANDCACHE[*]}-1] # pop read random number
};
# test by generating a lot of random numbers, then effectively place them in bins and count how many are in each bin.
declare -i c; declare -ia BIN
for (( c=0; c<100000; c++ )); do
rand 10
BIN[RET]+=1 # add to bin to check distribution
done
for (( c=0; c<10; c++ )); do
printf "%d %d\n" $c ${BIN[c]}
done
UPDATE: That does not work so well for all N. It also wastes random bits if used with small N. Noting that (in this case) a 32 bit random number has enough entropy for 9 random numbers between 0 and 9 (10*9=1,000,000,000 <= 2*32) we can extract multiple random numbers from each 32 random source value.
#!/bin/bash
declare -ia RCACHE
declare -i RET # return value
declare -i ENT=2 # keep track of unused entropy as 2^(entropy)
declare -i RND=RANDOM%ENT # a store for unused entropy - start with 1 bit
declare -i BYTES=4 # size of unsigned random bytes returned by od
declare -i BITS=8*BYTES # size of random data returned by od in bits
declare -i CACHE=16 # number of random numbers to cache
declare -i MAX=2**BITS # quantum of entropy per cached random number
declare -i c
function rand(){ # pick a random number from 0 to 2^BITS-1
[[ ${#RCACHE[*]} -eq 0 ]] && { RCACHE=( $(od -An -tu$BYTES -N$CACHE /dev/urandom) ); } # refill cache - could use /dev/random if CACHE is small
RET=${RCACHE[-1]} # pull last random number and scale
unset RCACHE[${#RCACHE[*]}-1] # pop read random number
};
function randBetween(){
local -i N=$1
[[ ENT -lt N ]] && { # not enough entropy to supply ln(N)/ln(2) bits
rand; RND=RET # get more random bits
ENT=MAX # reset entropy
}
RET=RND%N # random number to return
RND=RND/N # remaining randomness
ENT=ENT/N # remaining entropy
};
declare -ia BIN
for (( c=0; c<100000; c++ )); do
randBetween 10
BIN[RET]+=1
done
for c in ${BIN[*]}; do
echo $c
done

- 4,042
- 3
- 28
- 33
-
I tried this - it took 10 seconds of 100% cpu and then printed 10 numbers that didn't look random at ALL. – Carlo Wood Nov 18 '14 at 18:13
-
I remember now. This code generates 100,000 random numbers. It puts each in a 'bin' to look at how random it is. There are 10 bins. These numbers should be similar if each random number between 0 and 9 is equally likely. If you want to print each number, echo $RET after randBetween 10. – philcolbourn Nov 20 '14 at 13:07
-
`od -An -tu4 -N40 /dev/urandom` will generate 10 random unsigned 32 bit integers separated with whitespace. you can store it in an array and use it afterwards. your code seems to be an overkill. – Ali Nov 30 '15 at 15:53
-
@Ali, OP did not specify that they wanted 32 bit nor any other sized random number. I and some others interpreted this question as providing a random number within a range. My rand function achieves this goal and also reduces loss of entropy that, if exhausted, causes programs to block. od on /dev/urandom returns only 2^N bit random numbers and OP would then need to store multiple values into an array, sequentially extracting them from this array, and replenishing this array. Perhaps you can code this as an answer and handle other random number ranges? – philcolbourn Dec 01 '15 at 13:21
-
@philcolbourn, you are correct about the OP not specifying what kind of random number he wants and it missed my attention. But he only asked: "How to generate **a** random number in bash?". My point is that he only asked for one random number. Albeit this critic applies to my previous comment (generating **10** random numbers) as well. – Ali Dec 02 '15 at 11:51
Maybe I am a bit too late, but what about using jot
to generate a random number within a range in Bash?
jot -r -p 3 1 0 1
This generates a random (-r
) number with 3 decimal places precision (-p
). In this particular case, you'll get one number between 0 and 1 (1 0 1
). You can also print sequential data. The source of the random number, according to the manual, is:
Random numbers are obtained through arc4random(3) when no seed is specified, and through random(3) when a seed is given.

- 1,683
- 2
- 14
- 24
Pure Bash random number without moduloing
lowerRange=10 # inclusive
upperRange=20 # exclusive
randomNumber=$(( RANDOM * ( upperRange - lowerRange) / 32767 + lowerRange ))

- 382
- 4
- 10
-
-
using lowerRange=1 and upperRange=1000000 this solution works while others with % won't, – philippe lhardy Mar 09 '23 at 08:13
Generate random number in the range of 0 to n (signed 16-bit integer). Result set in $RAND variable. For example:
#!/bin/bash
random()
{
local range=${1:-1}
RAND=`od -t uI -N 4 /dev/urandom | awk '{print $2}'`
let "RAND=$RAND%($range+1)"
}
n=10
while [ $(( n -=1 )) -ge "0" ]; do
random 500
echo "$RAND"
done

- 329
- 2
- 5
What about:
perl -e 'print int rand 10, "\n"; '

- 396
- 1
- 3
- 5
-
2For a cryptographically secure random number, you need to read from /dev/urandom or use the Crypt::Random libraries. – k-h Jan 30 '19 at 21:59
You can use a seed, see documentation:
RANDOM=$(date +%s%N | cut -b10-19)
echo $(( $RANDOM % 100 + 1 ))
Based on the great answers of @Nelson, @Barun and @Robert, here is a Bash script that generates random numbers.
- Can generate how many digits you want.
- each digit is separately generated by
/dev/urandom
which is much better than Bash's built-in$RANDOM
#!/usr/bin/env bash
digits=10
rand=$(od -A n -t d -N 2 /dev/urandom |tr -d ' ')
num=$((rand % 10))
while [ ${#num} -lt $digits ]; do
rand=$(od -A n -t d -N 1 /dev/urandom |tr -d ' ')
num="${num}$((rand % 10))"
done
echo $num

- 41
- 4
Random branching of a program or yes/no; 1/0; true/false output:
if [ $RANDOM -gt 16383 ]; then # 16383 = 32767/2
echo var=true/1/yes/go_hither
else
echo var=false/0/no/go_thither
fi
of if you lazy to remember 16383:
if (( RANDOM % 2 )); then
echo "yes"
else
echo "no"
fi

- 466
- 4
- 11
Wanted to use /dev/urandom without dd and od
function roll() { local modulus=${1:-6}; echo $(( 1 + 0x$(env LC_CTYPE=C tr -dc '0-9a-fA-F' < /dev/urandom | head -c5 ) % $modulus )); }
Testing
$ roll
5
$ roll 12
12
Just how random is it?
$ (echo "count roll percentage"; i=0; while [ $i -lt 10000 ]; do roll; i=$((i+1)); done | sort | uniq -c | awk '{print $0,($1/10000*100)"%"}') | column -t
count roll percentage
1625 1 16.25%
1665 2 16.65%
1646 3 16.46%
1720 4 17.2%
1694 5 16.94%
1650 6 16.5%

- 1,281
- 7
- 11
Generate random 3-digit number
This is great for creating sample data. Example: put all testing data in a directory called "test-create-volume-123", then after your test is done, zap the entire directory. By generating exactly three digits, you don't have weird sorting issues.
printf '%02d\n' $((1 + RANDOM % 100))
This scales down, e.g. to one digit:
printf '%01d\n' $((1 + RANDOM % 10))
It scales up, but only to four digits. See above as to why :)

- 14,394
- 4
- 46
- 40
Here is a function I wrote which will output a random number in a desired range>
Description:
random <min> <max>
Generate a random number from
min
tomax
, inclusive. Bothmin
andmax
can be positive OR negative numbers, and the generated random number can be negative too, so long as the range(max - min + 1)
is less than or equal to32767
. Max must be >= min.
The core of it is this:
random() {
min="$1"
max="$2"
range=$((max - min + 1))
rand=$((min + (RANDOM % range)))
echo "$rand"
}
Usage:
# general form: obtain a random number between min and max, inclusive
random <min> <max>
# Example: obtain a random number from -10 to 10, inclusive
random -10 10
This works from the bash built-in variable RANDOM
, which probably just uses C rand()
under the hood, since they both have a max value of 32767--see:
- https://en.cppreference.com/w/c/numeric/random/rand
- https://en.cppreference.com/w/c/numeric/random/RAND_MAX
For the bash documentation, see man bash
:
RANDOM
Each time this parameter is referenced, a random integer between
0
and32767
is generated. The sequence of random numbers may be initialized by assigning a value toRANDOM
. IfRANDOM
isunset
, it loses its special properties, even if it is subsequently reset.
Robust, runnable, source
able version of the script
Here is a much more robust version of my random
function above. It includes full error checking, bounds checking, a help menu via random --help
or random -h
, and a special run_check
feature which allows you to source OR run this script so that you can source
it to import the random
function into any other script--just like you can do in Python!
random.sh <-- click this link to always get the latest version from my eRCaGuy_dotfiles repo.
RETURN_CODE_SUCCESS=0
RETURN_CODE_ERROR=1
HELP_STR="\
Generate a random integer number according to the usage styles below.
USAGE STYLES:
'random'
Generate a random number from 0 to 32767, inclusive (same as bash variable 'RANDOM').
'random <max>'
Generate a random number from 0 to 'max', inclusive.
'random <min> <max>'
Generate a random number from 'min' to 'max', inclusive. Both 'min' and 'max' can be
positive OR negative numbers, and the generated random number can be negative too, so
long as the range (max - min + 1) is less than or equal to 32767. Max must be >= min.
This file is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
"
print_help() {
echo "$HELP_STR" | less -RFX
}
# Get a random number according to the usage styles above.
# See also `utils_rand()` in utilities.c:
# https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/utilities.c#L176
random() {
# PARSE ARGUMENTS
# help menu
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
print_help
exit $RETURN_CODE_SUCCESS
fi
# 'random'
if [ $# -eq 0 ]; then
min=0
max="none"
# 'random max'
elif [ $# -eq 1 ]; then
min=0
max="$1"
# 'random min max'
elif [ $# -eq 2 ]; then
min="$1"
max="$2"
else
echo "ERROR: too many arguments."
exit "$RETURN_CODE_ERROR"
fi
# CHECK FOR ERRORS
if [ "$max" = "none" ]; then
rand="$RANDOM"
echo "$rand"
exit "$RETURN_CODE_SUCCESS"
fi
if [ "$max" -lt "$min" ]; then
echo "ERROR: max ($max) < min ($min). Max must be >= min."
exit "$RETURN_CODE_ERROR"
fi
# CALCULATE THE RANDOM NUMBER
# See `man bash` and search for `RANDOM`. This is a limitation of that value.
RAND_MAX=32767
range=$((max - min + 1))
if [ "$range" -gt "$RAND_MAX" ]; then
echo "ERROR: the range (max - min + 1) is too large. Max allowed = $RAND_MAX, but actual" \
"range = ($max - $min + 1) = $range."
exit "$RETURN_CODE_ERROR"
fi
# NB: `RANDOM` is a bash built-in variable. See `man bash`, and also here:
# https://stackoverflow.com/a/1195035/4561887
rand=$((min + (RANDOM % range)))
echo "$rand"
}
# Set the global variable `run` to "true" if the script is being **executed** (not sourced) and
# `main` should run, and set `run` to "false" otherwise. One might source this script but intend
# NOT to run it if they wanted to import functions from the script.
# See:
# 1. *****https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/argument_parsing__3_advanced__gen_prog_template.sh
# 1. my answer: https://stackoverflow.com/a/70662049/4561887
# 1. https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/check_if_sourced_or_executed.sh
run_check() {
# This is akin to `if __name__ == "__main__":` in Python.
if [ "${FUNCNAME[-1]}" == "main" ]; then
# This script is being EXECUTED, not sourced
run="true"
fi
}
# ----------------------------------------------------------------------------------------------------------------------
# Main program entry point
# ----------------------------------------------------------------------------------------------------------------------
# Only run main function if this file is being executed, NOT sourced.
run="false"
run_check
if [ "$run" == "true" ]; then
random "$@"
fi

- 36,492
- 15
- 194
- 265
-
TODO: make a new answer with a modern C++-based `uniform_int_distribution`, auto-built for your Linux system, and called in Bash. [See here](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/issues/14). – Gabriel Staples Feb 03 '23 at 15:51
A bash function that uses perl to generate a random number of n digits. Specify either the number of digits or a template of n 0s.
rand() {
perl -E '$ARGV[0]||=""; $ARGV[0]=int($ARGV[0])||length($ARGV[0]); say join "", int(rand(9)+1)*($ARGV[0]?1:0), map { int(rand(10)) } (0..($ARGV[0]||0)-2)' $1
}
Usage:
$ rand 3
381
$ rand 000
728
Demonstration of calling rand n, for n between 0 and 15:
$ for n in {0..15}; do printf "%02d: %s\n" $n $(rand $n); done
00: 0
01: 3
02: 98
03: 139
04: 1712
05: 49296
06: 426697
07: 2431421
08: 82727795
09: 445682186
10: 6368501779
11: 51029574113
12: 602518591108
13: 5839716875073
14: 87572173490132
15: 546889624135868
Demonstration of calling rand n, for n a template of 0s between length 0 and 15
$ for n in {0..15}; do printf "%15s :%02d: %s\n" $(printf "%0${n}d" 0) $n $(rand $(printf "%0${n}d" 0)); done
0 :00: 0
0 :01: 0
00 :02: 70
000 :03: 201
0000 :04: 9751
00000 :05: 62237
000000 :06: 262860
0000000 :07: 1365194
00000000 :08: 83953419
000000000 :09: 838521776
0000000000 :10: 2355011586
00000000000 :11: 95040136057
000000000000 :12: 511889225898
0000000000000 :13: 7441263049018
00000000000000 :14: 11895209107156
000000000000000 :15: 863219624761093

- 111
- 4
No other dependency is needed:
$(((RANDOM % $((upperBound - lowerBound))) + lowerBound))
The random number range is [lowerBound,upperBound)

- 121
- 6
random numbers from 001 to 087
$ printf "%03d" $(shuf -i 1-87 -n 1 )
As an example of actually using it, the Aleph With Beth videos all look something like:
039 - Verbs come & go (qatal singular) - Lesson 21.mp4
and this command:
$ mpv -fs $(printf "%03d" $(shuf -i 1-87 -n 1 ))*
plays a random video from the first 87, for revision purposes.

- 17,124
- 11
- 67
- 110