再初期化ランダム再初期化

再初期化ランダム再初期化

他のコンテキストで変数を使用しない場合、$RANDOM変数を印刷すると同じ結果が表示されます。zshこれは、シェルにコマンド出力または変数値のキャッシュがあるため、新しい値を取得できないのと同じです。私はこれを実行しています:

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

これは2回同じ結果$RANDOMであり、他の連続実行でもまだ最初の実行と同じ結果が得られます。

それでも同じことをします。printf \\$(printf "%o" $(( $(echo $RANDOM) % 123)))\\$(printf "%o" $(( $(echo $RANDOM) % 123)))

答え1

の財産ですzsh。またman zshparam見てくださいRANDOM

RANDOM値は、意図的に繰り返される疑似乱数シーケンスを形成します。 RANDOM を参照するサブシェルは、RANDOM 値がサブシェル呼び出しの間に親シェルで参照またはシードされない限り、同じ擬似乱数値を生成します。

内部サブシェルを評価しているため、$RANDOM予想される結果は次のとおりです。

$ 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

親シェルで使用されるたびに、$RANDOM後続のサブシェルには擬似ランダムな順序で次の番号が割り当てられます。ただし、子シェルは親シェルに影響を与えないため、$RANDOM親シェルを再利用すると数字が繰り返されます。

答え2

両方のサブシェルで同じ値が得られますが、$RANDOMここではサブシェルは必要ありません。

指定された値(または算術式)に対応する文字を取得するには、#パラメータ拡張フラグを使用できます。

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

ここで、このフラグは匿名関数のパラメータに適用されます。

以下を使用してもprintfサブシェルを作成する必要はありません。

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

マルチバイトロケールでは、#パラメータ拡張フラグはwchar_t値に対応する文字を提供します。 GNUシステムでは、これはUnicodeコードポイントです。

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

関連情報