use*_*781 1 zsh random command-substitution subshell
我有这个脚本从定义的字符列表中生成 $1 位的混合随机字符作为数组。
#!/bin/bash
charlist1=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
charlist2=(0 1 2 3 4 5 6 7 8 9)
charlists=(${charlist1[*]} ${charlist2[*]})
i="1"
while [ $i -le $1 ]; do
out=$out`echo -n ${charlists[$(($RANDOM % ${#charlists[*]}))]}`
i=$(( i + 1 ))
done
echo $out
Run Code Online (Sandbox Code Playgroud)
它在 bash 中运行良好,但是如果我用 zsh 调用它,zsh that_script_above.sh 6它只会生成 6 位相同字符的数字,如下所示:
>>> zsh that_script_above.sh 6
llllll
>>> zsh that_script_above.sh 6
bbbbbb
Run Code Online (Sandbox Code Playgroud)
如果我将该脚本修改为如下所示:
#!/bin/bash
charlist1=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
charlist2=(0 1 2 3 4 5 6 7 8 9)
charlists=(${charlist1[*]} ${charlist2[*]})
i="1"
while [ $i -le $1 ]; do
echo -n ${charlists[$(($RANDOM % ${#charlists[*]}))]}
i=$(( i + 1 ))
done
echo
Run Code Online (Sandbox Code Playgroud)
它可以很好地满足我对bash和 的期望zsh。
所以,这是我的问题:
for i in {1..$1}在 bash 中不起作用。一季度。命令替换(反引号)使用子外壳,并且在 zsh 中子外壳的 RNG 状态未重新设定种子。由于您重复创建一个新的子外壳而不$RANDOM在父外壳中使用,因此在每个子外壳中都会获得相同的值。请参阅:
https : //stackoverflow.com/questions/32577117/references-to-random-in-subshells-all-returning-identical-values
https://superuser.com/questions/1210435/different-behavior-of-in -zsh-and-bash-functions
您不需要 command-substitution 和 echo,也不需要 the$((..))因为数组下标已经被评估为算术表达式,但是您确实需要 +1 因为 zsh 数组是 1-origin(你很幸运没有碰巧打到 0):
out=$out${charlists[ $RANDOM % ${#charlists[*]} + 1 ]}
Run Code Online (Sandbox Code Playgroud)
旁白:即使您确实需要echo在命令中替换,您也不需要,-n因为命令替换本身会从捕获和替换的数据中删除任何尾随换行符。
Q2。bash 在进行参数扩展(以及命令和算术替换/扩展)之前先进行大括号扩展,但 zsh(和 ksh)在它之后进行。你可以使用for i in $(seq 1 $1)or yucky 但内置for i in $(eval "echo {1..$n}")
| 归档时间: |
|
| 查看次数: |
654 次 |
| 最近记录: |