このスクリプトを使用して、配列として定義された文字リストから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
Bashでは正常に動作しますが、zsh that_script_above.sh 6
によってzshで呼び出すと、次のような同じ文字の6桁が生成されます。
>>> zsh that_script_above.sh 6
llllll
>>> zsh that_script_above.sh 6
bbbbbb
そして、そのスクリプトを次のように変更した場合:
#!/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
bash
とzsh
の両方で希望どおりに機能します。
だから、ここに私の質問があります:
for i in {1..$1}
はbashでは機能しないようです。Q1。コマンド置換(バッククォート)はサブシェルを使用し、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
コマンド置換とエコーは必要ありません。また、配列の添え字はすでに算術式として評価されているため、$((..))
も必要ありませんが、zsh配列は1であるため、+ 1が必要です。 -起源(あなたは幸運にも0をヒットしなかった):
_ out=$out${charlists[ $RANDOM % ${#charlists[*]} + 1 ]}
_
余談ですが、コマンド置換でecho
が必要だったとしても、コマンド置換自体がキャプチャされて置換されたデータから末尾の改行を削除するため、_-n
_は必要ありません。
Q2。 bashは、パラメーター拡張(およびコマンドおよび算術置換/拡張)を実行する前に中括弧拡張を実行しますが、zsh(およびksh)は後で実行します。 for i in $(seq 1 $1)
またはyuckyを使用できますが組み込みのfor i in $(eval "echo {1..$n}")