env
どちらprintenv
も外部コマンド、つまりbash組み込みコマンドではなく実行可能ファイルです。問題は、それらが出力するいくつかの環境変数(つまり、より多くが_
あるかどうかを知りたい)がそれを呼び出すシェルに属していないことです。ここ。
答え1
declare -x
または、エクスポートされたとマークされたすべての変数を一覧表示します。、これからもそうだろうexport
:
$ declare -x
declare -x ALTERNATE_EDITOR=""
declare -x COLORFGBG="7;0"
declare -x COMMAND_MODE="unix2003"
...
declare -x VISUAL="gvim"
エクスポートされていないローカル変数は一覧表示されませんが、シェルの外部環境から継承された変数は含まれます。
declare -x -F -p
エクスポートされた関数はすべて省略されます。
答え2
Bashのマニュアルのフレーズに注意してください:「すべての変数目立つ私たちは、プロセスの「環境」をシステムコールへenvp
の引数として渡すのと、execve
この引数を通して渡されるだけだと思います。残りは単なる幻想です。呼び出しプロセス(シェルまたは他の種類のプロセス)は、文書化された動作方法に応じて受け取った変数で何でもできます。受け取った変数を子プロセスに渡すことも、そうしないように選択することもできます。
私の目標は、親プロセスから子プロセスに自動的に渡される環境変数の魔法のブロックがないことです。親プロセスは、独自の「環境」を使用して目的のタスクを実行し、クラックし、メモリから暗号化し、プロセススペースの別のアドレスにコピーする(Bashが実行するタスク)などを実行できます。プロセス環境を確認するための外部メカニズムやカーネルメカニズムはありません。 (しばらくお待ちください。/proc/PID/environ
以下の説明をお読みください。)唯一の重要な点は、エクスポートプロセスがBashの独自の規則に従ってフラグメントを収集し、環境をサブプロセスに渡す必要があることです。ルールは Bash のマニュアルに記載されています。
これは文書が/proc/$$/environ
欺瞞的であることを意味します。これはシェル環境への変更は反映しませんが、親プロセスexec
で単に編集したときにシェルが受け取った内容を報告します。
答え3
いいえ、そこではありません。
これには3つの「変数」セットがあります。
- Bourne Againシェルは、それを作成して実行するすべての親プロセスから環境変数セットを継承します。これは、寿命を通してBourne Againシェルプロセスの環境変数として保持されます。
- これらの環境変数は2番目のセットを初期化します。シェル変数Bourne Againシェルを使用すると、ユーザーは
declare
。 - 2番目のシェル変数セットは、どのシェル変数が使用されるかを決定します。輸出可能としてマーク
execve
(およびこの回答の範囲外のいくつかの異なるメカニズム)そのサブプロセスで外部コマンドを実行するためにBourne Againシェル自体から生成されたサブプロセスによって継承される環境変数は何ですか?
最初のグループは「現在のシェルの環境変数」です。 2番目のグループはシェル変数、3番目のグループは環境変数です。サブプロセスの。
Bourne Againシェルはプロセス環境変数を変更し、その変更を他のプロセスに表示できますが、私が説明したように、プログラムは次のことを行うことができます。https://unix.stackexchange.com/a/432681/5132実際、Bourne Againシェルはこれを行いません。
同様に、Bourne Againシェルは環境変数へのアクセスを提供できますが、そうではなく、環境変数へのアクセスのみを提供します。シェル変わりやすい~からシェルプログラムの起動時に対応する環境変数。
(この質問のためにBourne Againシェルに言及しましたが、実際にはほとんどのシェルは同様に機能しますが、これはBourne Againシェルに限定されていません。)
もちろん、外部プログラムは3番目の変数セットが好きでenv
表示されます。printenv
現在のシェルプロセスの環境変数を表示するには、外部コマンドを使用する必要があります。
PS ewwww -p$$または
hexdump -C /compat/linux/proc/$$/environ(
/proc
Linuxオペレーティングシステムのみ)
追加読書
答え4
declare -p
一覧表示されますすべてそうだ。 「環境変数」はローカルシェル変数をエクスポートするのではなく、技術的にエクスポートした変数なので、あなたの質問は少し誤解を招く可能性があります。