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

kor*_*rda 3 zsh random

这:

\n\n
woof() {\n\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82\xe2\x80\x82/usr/bin/woof -p $(expr $RANDOM % 32768 + 1024) $@\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n

use*_*686 5

$( )事实上,RNG 的表现是一样的,但 RNG 却不是这样。

\n\n

看来zsh RNG只是在引用该值后才前进,但在分叉时没有重新播种。这意味着子 shell 将继续从父进程继承旧种子,因为子 shell 中发生的任何更改都不会影响父进程。使用$[\xe2\x80\xa6]不会有这个问题,因为它不会创建子shell。

\n\n

根据zshall(1)手册页:

\n\n
   RANDOM <S>\n          A pseudo-random integer from 0 to 32767, newly generated each time\n          this  parameter is referenced.  The random number generator can be\n          seeded by assigning a numeric value to RANDOM.\n\n          The values of RANDOM form an intentionally-repeatable  pseudo-ran\xe2\x80\x90\n          dom sequence; subshells that reference RANDOM will result in iden\xe2\x80\x90\n          tical pseudo-random values unless the value of  RANDOM  is  refer\xe2\x80\x90\n          enced  or  seeded  in the parent shell in between subshell invoca\xe2\x80\x90\n          tions.\n
Run Code Online (Sandbox Code Playgroud)\n\n

测试:

\n\n
% echo outer=$RANDOM; (echo inner=$RANDOM); (echo inner=$RANDOM);\nouter=10246\ninner=5606\ninner=5606\n
Run Code Online (Sandbox Code Playgroud)\n