如果我不在其他上下文中使用变量,则打印$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