223

How would I generate an inclusive random number between 1 to 10 in Bash Shell Script?

Would it be $(RANDOM 1+10)?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
A15
  • 2,345
  • 2
  • 15
  • 7

6 Answers6

380
$(( ( RANDOM % 10 )  + 1 ))

EDIT. Changed brackets into parenthesis according to the comment. http://web.archive.org/web/20150206070451/http://islandlinux.org/howto/generate-random-numbers-bash-scripting

toxefa
  • 283
  • 2
  • 10
OrangeTux
  • 11,142
  • 7
  • 48
  • 73
  • 1
    I get a syntax error: syntax error near unexpected token `+' on Linux – Spaceghost Aug 19 '13 at 17:57
  • 43
    The `% 10` reduces the result to a set of ranges from 0-9. However, the very top set only has a range of 0-7. Thus, there are two fewer draws for 8 & 9 than 0-7. The + 1 translates this to a bias against 9 & 10. This would be a major flaw in security contexts - an RNG must not display bias, and at scale this is noticeable. Further explanation: [Anatomy of a pseudorandom number generator - visualising Cryptocat's buggy PRNG](http://nakedsecurity.sophos.com/2013/07/09/anatomy-of-a-pseudorandom-number-generator-visualising-cryptocats-buggy-prng/). – Brad Koch Sep 18 '13 at 19:02
  • @BradKoch How do we know that Bash's RNG makes that error? – Ads20000 Feb 13 '17 at 16:12
  • 5
    @ads20000 The docs say so, `man bash`, "Each time this parameter is referenced, a random integer between 0 and 32767 is generated." Note that this is not a bash error, it's an error of the implementer. Assuming bash implemented `$RANDOM` correctly, there should be a fair draw from numbers 0 to 32767, but because you can't divide that evenly into groups of 10, there is a very small bias against 9 and 10 in this implementation. Most people shouldn't need to worry about this, because you shouldn't be using `$RANDOM` for security purposes anyway. – Brad Koch Feb 13 '17 at 16:22
  • By far the simplest solution – hmedia1 Nov 07 '19 at 00:57
  • this works for what I need `export CUDA_VISIBLE_DEVICES=$((( RANDOM % 8 )))` – Charlie Parker Mar 11 '21 at 20:47
115

Simplest solution would be to use tool which allows you to directly specify ranges, like shuf

shuf -i1-10 -n1

If you want to use $RANDOM, it would be more precise to throw out the last 8 numbers in 0...32767, and just treat it as 0...32759, since taking 0...32767 mod 10 you get the following distribution

0-8 each: 3277 
8-9 each: 3276

So, slightly slower but more precise would be

while :; do ran=$RANDOM; ((ran < 32760)) && echo $(((ran%10)+1)) && break; done 
Reinstate Monica Please
  • 11,123
  • 3
  • 27
  • 48
  • I found this question looking for `/bin/sh` even though the question requests bash. The `shuf` technique appears to work in both bash and sh. – jia103 Jan 14 '22 at 05:01
43

To generate random numbers with bash use the $RANDOM internal Bash function. Note that $RANDOM should not be used to generate an encryption key. $RANDOM is generated by using your current process ID (PID) and the current time/date as defined by the number of seconds elapsed since 1970.

 echo $RANDOM % 10 + 1 | bc
shadyabhi
  • 16,675
  • 26
  • 80
  • 131
32

You can also use /dev/urandom:

grep -m1 -ao '[0-9]' /dev/urandom | sed s/0/10/ | head -n1
choroba
  • 231,213
  • 25
  • 204
  • 289
25

To generate in the range: {0,..,9}

r=$(( $RANDOM % 10 )); echo $r

To generate in the range: {40,..,49}

r=$(( $RANDOM % 10 + 40 )); echo $r

Thomas Bratt
  • 48,038
  • 36
  • 121
  • 139
-6

Here is example of pseudo-random generator when neither $RANDOM nor /dev/urandom is available

echo $(date +%S) | grep -o .$ | sed s/0/10/

l0pan
  • 476
  • 7
  • 11