zsh 和 bash 函数中 $(…$RANDOM…) 的不同行为

zsh 和 bash 函数中 $(…$RANDOM…) 的不同行为

这:

woof() {
        /usr/bin/woof -p $(expr $RANDOM % 32768 + 1024) $@
}

在 zsh 上,参数 -p 总是返回相同的数字。在 bash 中,$(...)每次调用都会进行评估。对我来说,用“修复”替换$( ... )zsh$[ ... ]中的这个“问题”但导致意外行为(至少对我来说是意外的)的问题或差异是什么?

答案1

$( )实际上其行为方式相同,但 RNG 却不是这样。

似乎 zsh RNG 仅在引用该值后才会前进,但在分叉时不会重新播种。这意味着子 shell 将继续从父进程继承旧种子,因为子 shell 中发生的任何更改都不会影响父进程。使用$[…]不会出现此问题,因为它不会创建子 shell。

根据zshall(1)手册页:

   RANDOM <S>
          A pseudo-random integer from 0 to 32767, newly generated each time
          this  parameter is referenced.  The random number generator can be
          seeded by assigning a numeric value to RANDOM.

          The values of RANDOM form an intentionally-repeatable  pseudo-ran‐
          dom sequence; subshells that reference RANDOM will result in iden‐
          tical pseudo-random values unless the value of  RANDOM  is  refer‐
          enced  or  seeded  in the parent shell in between subshell invoca‐
          tions.

测试:

% echo outer=$RANDOM; (echo inner=$RANDOM); (echo inner=$RANDOM);
outer=10246
inner=5606
inner=5606

相关内容