重新初始化 随机重新初始化

重新初始化 随机重新初始化

如果我不在其他上下文中使用变量,则打印$RANDOM变量会给出相同的结果。zsh这就像 shell 有一个命令输出或变量值的缓存,所以我无法获得新值。我正在运行这个:

zsh $ printf \\$(printf "%o" $(( $RANDOM % 123)))\\$(printf "%o" $(( $RANDOM % 123)))

这是相同结果的两次$RANDOM,并且在不同的连续运行中,我仍然得到与第一次运行相同的结果。

仍然得到完全相同的行为printf \\$(printf "%o" $(( $(echo $RANDOM) % 123)))\\$(printf "%o" $(( $(echo $RANDOM) % 123)))

答案1

它是 的财产zsh。另请man zshparam参阅RANDOM

RANDOM 的值形成有意重复的伪随机序列;引用 RANDOM 的子 shell 将产生相同的伪随机值,除非在子 shell 调用之间在父 shell 中引用或播种 RANDOM 的值。

您正在评估$RANDOM内部子 shell,因此这是预期的结果:

$ RANDOM=123
$ echo $(echo $RANDOM) $(echo $RANDOM) $(echo $RANDOM)
17313 17313 17313

bash 或 busybox ash 中的相同命令:

$ echo $(echo $RANDOM) $(echo $RANDOM) $(echo $RANDOM)
12554 22752 18907

不同的外壳,不同的行为。


不同的例子zsh

$ RANDOM=123
$ echo $RANDOM $(echo $RANDOM) $RANDOM $(echo $RANDOM) $RANDOM    
17313 7829 7829 9329 9329

每当父 shell 使用 时$RANDOM,后面的子 shell 都会给出伪随机序列中的下一个数字。但由于子shell不影响父shell,所以当父shell$RANDOM再次使用时,数字会重复。

答案2

您将从两个子 shell 中获得相同的$RANDOM值,但在这里您不需要子 shell。

要获取给定值(甚至算术表达式)对应的字符,可以使用#参数扩展标志:

$ (){ printf %s ${(#)argv}; } RANDOM%123 RANDOM%123
KU

这里该标志应用于匿名函数的参数。

即使使用printf,您也不需要生成子shell:

$ printf -v var '\\%o' RANDOM%123 RANDOM%123
$ print $var
D#

请注意,在多字节语言环境中,#参数扩展标志将为您提供与 wchar_t 值对应的字符。在 GNU 系统上,这是 Unicode 代码点。

$ () { print ${(#)1}; } 128039

相关内容