How to run a command 1 out of N times in Bash
In ksh
, Bash, Zsh, Yash or BusyBox sh
:
[ "$RANDOM" -lt 3277 ] && do_stuff
The RANDOM
special variable of the Korn, Bash, Yash, Z and BusyBox shells produces a pseudo-random decimal integer value between 0 and 32767 every time it’s evaluated, so the above gives (close to) a one-in-ten chance.
You can use this to produce a function which behaves as described in your question, at least in Bash:
function chance {
[[ -z $1 || $1 -le 0 ]] && return 1
[[ $RANDOM -lt $((32767 / $1 + 1)) ]]
}
Forgetting to provide an argument, or providing an invalid argument, will produce a result of 1, so chance && do_stuff
will never do_stuff
.
This uses the general formula for “1 in n” using $RANDOM
, which is [[ $RANDOM -lt $((32767 / n + 1)) ]]
, giving a (⎣32767 / n⎦ + 1) in 32768 chance. Values of n
which aren’t factors of 32768 introduce a bias because of the uneven split in the range of possible values.
Non-standard solution:
[ $(date +%1N) == 1 ] && do_stuff
Check if the last digit of the current time in nanoseconds is 1!
An alternative to using $RANDOM
is the shuf
command:
[[ $(shuf -i 1-10 -n 1) == 1 ]] && do_stuff
will do the job. Also useful for randomly selecting lines from a file, eg. for a music playlist.