如何在 Bash 中运行 N 次中的 1 个命令

ret*_*ikt 15 bash gnu coreutils random shell-builtin

我想要一种随机运行命令的方法,比如 10 次中的 1 次。是否有内置或 GNU coreutil 来执行此操作,理想情况下是这样的:

chance 10 && do_stuff

哪里do_stuff只执行了 10 次?我知道我可以写一个脚本,但这似乎是一件相当简单的事情,我想知道是否有一种定义的方式。

Ste*_*itt 41

ksh、Bash、Zsh、Yash 或 BusyBox 中sh

[ "$RANDOM" -lt 3277 ] && do_stuff
Run Code Online (Sandbox Code Playgroud)

RANDOMKorn、Bash、Yash、Z 和 BusyBox shell的特殊变量每次计算时都会生成一个介于 0 和 32767 之间的伪随机十进制整数值,因此上述给出(接近)十分之一的机会。

您可以使用它来生成一个函数,该函数的行为与您的问题中描述的一样,至少在 Bash 中是这样:

function chance {
  [[ -z $1 || $1 -le 0 ]] && return 1
  [[ $RANDOM -lt $((32767 / $1 + 1)) ]]
}
Run Code Online (Sandbox Code Playgroud)

忘记提供参数或提供无效参数将产生 1 结果,因此chance && do_stuff永远不会do_stuff

这使用了“1 in n$RANDOM,即[[ $RANDOM -lt $((32767 / n + 1)) ]],给出了 (?32767 / n ? + 1) in 32768 的机会。n不是 32768 因子的值会引入偏差,因为可能值范围内的分割不均匀。


小智 25

非标解决方案:

[ $(date +%1N) == 1 ] && do_stuff

检查以纳秒为单位的当前时间的最后一位是否为 1!

  • @EricDuminil:不幸的是:1)系统时钟在合同中没有义务提供实际的纳秒分辨率(它可以四舍五入到最近的 [`clock_getres()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/ clock_getres.html)), 2) 不禁止调度器,例如,总是在 100 纳秒边界上启动时间片(即使时钟正确也会引入偏差),3) 支持的获取随机值的方式是(通常)从 `/dev/urandom` 读取或检查 `$RANDOM` 的值。 (9认同)
  • @XavierStuvw 我认为如果代码正在检查秒数,您会有一点意见。但是纳秒?它应该看起来非常随机。 (3认同)
  • 您必须确保调用 `[ $(date +%1N) == 1 ] && do_stuff` 不会定期发生,否则会破坏随机性。想想`虽然是真的; do [ $(date +1%N) == 1 ] && sleep 1; done` 作为一个抽象的反例。尽管如此,玩纳秒的想法真的很好,我想我会使用它,因此+1 (2认同)

seu*_*mac 21

使用的替代方法$RANDOMshuf命令:

[[ $(shuf -i 1-10 -n 1) == 1 ]] && do_stuff
Run Code Online (Sandbox Code Playgroud)

会做的工作。也可用于从文件中随机选择行,例如。对于音乐播放列表。


Eis*_*urr 12

改进第一个答案并使您想要实现的目标更加明显:

[ $(( $RANDOM % 10 )) == 0 ] && echo "You win" || echo "You lose"
Run Code Online (Sandbox Code Playgroud)