I want to run one of the two commands C1 and C2 at random. How do I do that on commandline (bash)? Will appreciate if a one-liner is possible.
3 Answers
if (( RANDOM % 2 )); then C1; else C2; fi
- 
        2Bear in mind that if you want a 1 in N odds of running C1, you must probably use(( RANDOM % N == 0 ))rather than(( RANDOM % N )). It's only the in special case of N=2 that these have identical probability.Asclepius– Asclepius2015-07-08 03:25:54 +00:00Commented Jul 8, 2015 at 3:25
- 
        2Plainly put, of what practical use would beRANDOM % $Nwithout== 0? IMO, for example with N=100, it is much more pragmatic to want a 1 in 100 odds (delivered with== 0) than a 99 in 100 odds (delivered without== 0).Asclepius– Asclepius2015-07-08 20:41:35 +00:00Commented Jul 8, 2015 at 20:41
In your special case:
C$((RANDOM%2+1))
will work :) And hey, it's the shortest answer!
- 
        Why does it need two sets of parentheses around it? I am just not very familiar with whatever you used.AJMansfield– AJMansfield2013-07-03 18:16:31 +00:00Commented Jul 3, 2013 at 18:16
- 
        2@AJMansfield$((1+1))->2, eg.$(( ))calculates what's inside.Tyilo– Tyilo2013-07-03 18:46:28 +00:00Commented Jul 3, 2013 at 18:46
- 
        3It would be even shorter if the OP chose C0 and C1. Maybe he's not a programmer?ott--– ott--2013-07-03 19:51:38 +00:00Commented Jul 3, 2013 at 19:51
- 
        2I'm pretty sure that C1 and C2 were placeholders rather than actual commands to run. :-)Chris Down– Chris Down2013-07-06 03:42:39 +00:00Commented Jul 6, 2013 at 3:42
- 
        1
You can do something like this in Bash:
$ (( RANDOM%2 == 0 )) && C1 || C2
This will generate a random number, either 0 or 1. If it's a 0, then C1 runs, otherwise C2 runs if it isn't.
example
$ (( RANDOM%2 == 0 )) && echo 0 || echo 1
1
$ (( RANDOM%2 == 0 )) && echo 0 || echo 1
0
NOTE: The first character, $, is the prompt.
another example
If you're concerned with C1 having to fail so that C2 can run you could restructure the above like so:
(( RANDOM%2 == 0 )) && CMD=C1 || CMD=C2
$CMD
why use this over a if/then statement?
This answer has been criticized a bit but there's a method to my madness. Though this pattern may seem more obscure than a if/then I find it more readable and compact when doing something like the following:
#!/bin/bash
CMD=""
DIRS="/etc /home /www /data1 /data2 /var/log /var/spool/mail"
FILE="/backup/$(hostname)-$(date +'%m-%d-%y').tar.gz"
[ "$1" == "nas" ]  && CMD="lftp -u user,password -e 'cd /dump/; mput /backup/*; quit' nas.mylan.com" || :
[ "$1" == "scp" ]  && CMD="scp /backup/* scponly@dumpserver:incoming' username" || :
[ "$1" == "tape" ] && CMD='tar -cf /dev/st0 /backup/*' || :
[ "$CMD" == "" ]   && exit 1 || :
# make a backup
tar -zcvf  $FILE $DIRS
# Now depend upon circumstances run a backup command
$CMD
References
- 
        2This will runC2ifC1fails, which violates the specification laid out in the question (namely, that only one of the commands is run).x && y || zis not equivalent toif x; then y; else z; fi.Chris Down– Chris Down2013-07-03 04:34:51 +00:00Commented Jul 3, 2013 at 4:34
- 
        
- 
        4The edit nominally fixes this, but it's really obscure. "If you're concerned with C1 having to fail so that C2 can run" doesn't capture the scenario at all. The issue is that ifC1is a command which sometimes returns a non-zero exit code, you will end up executing bothC1andC2when that happens.tripleee– tripleee2013-07-03 06:23:00 +00:00Commented Jul 3, 2013 at 6:23
- 
        +1 but use((...))instead of[...]-- double parentheses are specifically for arithmetic expressions.glenn jackman– glenn jackman2013-07-03 09:45:36 +00:00Commented Jul 3, 2013 at 9:45
- 
        One more simplification: you don't need$(())inside(())--(( RANDOM%2 == 0 ))glenn jackman– glenn jackman2013-07-03 11:59:22 +00:00Commented Jul 3, 2013 at 11:59

