Я хочу, чтобы команда запускалась случайным образом, скажем, 1 из 10 раз. Есть ли встроенный или GNU coreutil для этого, в идеале что-то вроде:
chance 10 && do_stuff
где do_stuff
выполняется только 1 в 10 раз? Я знаю, что мог бы написать сценарий, но это кажется довольно простой вещью, и мне было интересно, есть ли определенный путь.
Ответы:
В
ksh
Bash, Zsh, Yash или BusyBoxsh
:RANDOM
Специальная переменная Корн, Bash, Яш, Z и BusyBox оболочек производит псевдослучайное десятичное целое число в диапазоне от 0 до 32767 каждый раз , когда она оценена, так что выше , дает (близко к) на один из десяти случайно.Вы можете использовать это для создания функции, которая ведет себя так, как описано в вашем вопросе, по крайней мере, в Bash:
Если вы забудете предоставить аргумент или предоставите неверный аргумент, результат будет равен 1, поэтому
chance && do_stuff
никогда не будетdo_stuff
.При этом используется общая формула для «1 в n » с использованием
$RANDOM
, которая[[ $RANDOM -lt $((32767 / n + 1)) ]]
дает (⎣32767 / n ⎦ + 1) с вероятностью 32768. Значения,n
которые не являются факторами 32768, вносят смещение из-за неравномерного разделения диапазона возможных значений.источник
$((32767/parts+1))
бы больше 1, или мы рискуем увеличить число частей в 1, в то время как результат деления (и, следовательно, предел) был бы одинаковым. (продолжение)(32767/n-32767/(n+1))>=1
решение для n, которое дает предел в ~ 181,5. На самом деле количество деталей может доходить до 194 без проблем. Но в 195 частях результирующий предел составляет 151, тот же результат, что и в 194 частях. Это несовместимо, и его следует избегать. Короче говоря, верхний предел для количества частей (n) должен быть 194. Вы можете сделать предельные тесты:[[ -z $1 || $1 -le 1 || $1 -ge 194 ]] && return 1
Нестандартное решение:
[ $(date +%1N) == 1 ] && do_stuff
Проверьте, является ли последняя цифра текущего времени в наносекундах 1!
источник
[ $(date +%1N) == 1 ] && do_stuff
не происходит через равные промежутки времени, иначе случайность будет испорчена. Думайте об этомwhile true; do [ $(date +1%N) == 1 ] && sleep 1; done
как абстрактный контрпример. Тем не менее, идея игры с наносекундами действительно хороша, я думаю, что буду ее использовать, поэтому +1clock_getres()
), 2) Планировщику не запрещено, например, всегда запускать временной интервал на границе 100 наносекунд (что привело бы к смещению, даже если часы верны), 3) Поддерживаемый способ получения случайных значений - это (обычно) чтение/dev/urandom
или проверка значения$RANDOM
.Альтернативой использованию
$RANDOM
являетсяshuf
команда:сделаю работу. Также полезно для случайного выбора строк из файла, например. для музыкального плейлиста.
источник
Улучшение первого ответа и сделать намного более очевидным, что вы пытаетесь достичь:
источник
$RANDOM % 10
будет иметь смещение, если только он не произведет$RANDOM
ровно кратное 10 различным значениям (что обычно не происходит в двоичном компьютере)"$RANDOM" -lt $((32767 / n + 1))
.Я не уверен, хотите ли вы случайности или периодичности ... Для периодичности:
Вы можете смешать его с уловкой «$ RANDOM» выше, чтобы создать что-то более хаотичное, например:
ибо я в
seq 1 1000 $RANDOM
; сделать эхо $ я; сделаноHTH :-)
источник