回答:
RANDOM
環境変数ではありません。これは、いくつかのシェルによって維持されるシェル変数です。通常、デフォルトではエクスポートされません。これが、の出力に表示されない理由ですenv
。
それは少なくとも一度使用されていたら、それは考えの出力に表示さset
れ、それ自体で、リストのシェル変数(および機能)と、現在のシェルセッションではその値、。この動作はシェルに依存しておりpdksh
、OpenBSDでの使用は、以前に使用RANDOM
されset
ていなくてもリストされます。
この回答の残りの部分は、RANDOM
エクスポートされた場合(環境変数に変換された場合)に何が起こると予想されるかに関するものです。
でエクスポートするとexport RANDOM
環境変数になりますが、子プロセスでの値は「ランダムだが静的」であるため、使用は厳しく制限されます(つまり、変化しない乱数になることを意味します)。正確な動作はシェルによって異なります。
pdksh
以下の例でOpenBSD を使用していますが、awk
実行ごとに新しいランダム値を取得します(ただし、同じインスタンス内では毎回同じ値を取得しawk
ます)。を使用してbash
、すべての呼び出しでまったく同じランダム値を取得しますawk
。
$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
25444 25444
$ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
30906 30906
ではbash
、シェルRANDOM
での使用に関係なく、のエクスポートされた値は静的なままですRANDOM
(使用するたびに$RANDOM
新しい値が得られます)。
各参照するためですシェル変数 RANDOM
では、bash
シェルアクセスは、その内部になりget_random()
機能が変数に新しいランダムな値を与えることが、シェルは更新されない環境変数を RANDOM
。これは、他の動的と同様の挙動に類似しているbash
ような変数、LINENO
、SECONDS
、BASHPID
等
環境変数更新するにはRANDOM
ではbash
、あなたは、シェル変数の値を代入しなければならないRANDOM
と再輸出にそれを:
export RANDOM="$RANDOM"
これに乱数ジェネレーターを再シードする追加の副作用bash
があるかどうかはわかりません(しかし、経験に基づいた推測はそうではないということです)。
RANDOM
あなたがそれを使用する前にも、価値がありますか?呼び出されたときにのみデータが入力されると常に思っていました。
export RANDOM
またはを行うとdeclare -p RANDOM
、それが表示されるため、参照される前に存在しない使用であるかどうかは
シェルセッションで設定されるすべての変数が環境変数であるとは限りません。「環境変数」とは、export
ビルトインを使用して環境にエクスポートされた変数のみを指します。このenv
コマンドは、そのような環境変数のみを出力します。例えば:
$ foo="bar"
$ env | grep foo ## returns nothing
$ export foo
$ env | grep foo ## now, env will print it
foo=bar
セッションで設定されたすべての変数を、それらがエクスポートされたかどうかに関係なく表示する場合は、次を使用できますset
。
$ set | grep foo=
foo=bar
set
組み込みも機能を返すので、変数だけを見て、あなたが使用することができます。
set | grep '^[^[:space:]]*='
最後に、RANDOM
変数は、参照するときにのみ値が割り当てられるという点で特別です。これはbash(1)で言及されています:
RANDOM
このパラメーターが参照されるたびに、0〜32767のランダムな整数が生成されます。乱数のシーケンスは、に値を割り当てることで初期化できます
RANDOM
。場合はRANDOM
設定解除され、それがその後にリセットされている場合でも、その特殊な性質を失います。
だから、あなたが思ったように環境変数であってもenv
、最初に呼び出したときまで設定されないので、表示されませんでした。それが、set
以下に示されていない理由でもあります。
$ set | grep RAN ## returns nothing, RANDOM is unset
$ echo "$RANDOM" ## this will assign a value to RANDOM
1234
$ set | grep RAN ## so now it will also appear in the output of set
RANDOM=1234
set | grep RAN
です。私はそれを期待していなかっただろう。FWIW、ドキュメントでは予測できないと思います。
ほとんどのシェルには、デフォルトで子プロセスにエクスポートされないシェルによって設定または使用される他の変数がいくつかあります。
Bashには、明らかにBash固有のものがいくつかあります。
$ echo "${!BASH*}"
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
$ echo $BASH_VERSION
4.4.12(1)-release
$ env|grep -c BASH
0
そして、より多くの標準のようなものがありますOPTIND
し、OPTERR
(で使用されるgetopts
)、およびPS2
、PS3
(二次プロンプト)、さらには他の「マジック」変数SECONDS
(シェルが起動してから数秒でショータイム)
Bashでは、すべての変数とそのエクスポートステータスをで確認できますdeclare -p
。マークが付いて-x
いるものはエクスポートされ、x
ないものはエクスポートされません。(i
整数やr
読み取り専用など、他のフラグを持つものもあります。)
Zshまたはksh93では、使用できますtypeset -p
が、Zshはフラグを使用する代わりに、出力でに変更するtypeset
ことによりエクスポートされた変数をマークしますexport
。export
それ自体はエクスポートされたすべての変数も表示しますが、それはを実行して得られる結果とほぼ同じですenv
。
これをグーグルで検索した場合、ドキュメントには次のように記載されています。
$RANDOM
0〜32767の範囲の擬似乱数[1]整数を返す内部Bash 関数(定数ではありません)。暗号化キーの生成には使用しないでください。
使用strace
すると、$RANDOM
「変数」が通常のシェル変数または環境変数であるかのようにコマンドに直接渡されることがわかりますが、それはシェルに組み込まれている単なる内部関数であり、拡張を行っています。
$ strace -t echo "random value: $RANDOM"
04:37:58 execve("/bin/echo", ["echo", "random value: 30795"], [/* 27 vars */]) = 0
04:37:58 brk(NULL) = 0x19c1000
04:37:58 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9841351000
...
対この通常の変数:
$ strace -t echo "random value: $SOMEVAR"
04:40:19 execve("/bin/echo", ["echo", "random value: helloworld"], [/* 27 vars */]) = 0
04:40:19 brk(NULL) = 0x154b000
04:40:19 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f659d2eb000
...
変数は参照として渡されていません。
$RANDOM
または$SOMEVAR
コマンドライン引数を介して渡されませんか?export
これらを環境に渡すには両方が必要です。
strace
出力は、シェルによって実行内部関数をキャッチしていないようです。どちらの場合も、変数はの最初の行で既に展開されていますstrace
。私はあなたが指している違いを理解していません。私は何が欠けていますか?
$RANDOM
拡張がシェルに内部的に行われています。基本的には、シェルが値を決定し、変数への参照を渡さないことの確認です。シェルは、コマンドラインを展開して解析を実行し$RANDOM
、展開されたフォームをに渡しecho
ます。
env
通常はシェルに組み込まれないため、シェルコマンドではありません。