~からhttps://unix.stackexchange.com/a/436631/674
ファイル
/proc/$$/environ
...は、環境への変更を反映せず、単にexec
プロセスで編集したときにプログラムが受信した内容を報告します。
APUEから:
各プログラムには環境リストも渡されます。引数リストと同様に、環境リストは文字ポインタの配列であり、各ポインタはnullで終わるC文字列のアドレスを含みます。ポインタ配列のアドレスはグローバル変数に含まれています
environ
。extern char **environ;
特定の環境変数へのアクセスは通常、環境変数ではなく、
getenv
関数(セクション7.9で説明されている)を介して行われます。putenv
ただし、環境全体をナビゲートするにはenviron
ポインタを使用する必要があります。
/proc/$$/environ
environ
それらは互いに独立していますか、それともグローバル変数と一致しますか?
を介してアクセスされた文字environ
列も環境への変更を反映しませんが、receiveを介して環境のみを報告しますか execve()
?
それとも、常に最新の環境文字列を取得するかのように、アクセスする文字列はenviron
常に変更を反映していますか?getenv
を介してアクセスされる文字列は getenv
常に変更を反映し、常に最新の状態ですか?
ありがとうございます。
答え1
/proc/$$/environ
そして変数はenviron
独立しています。実際、環境変数がenviron
ポインタ値を介して環境に追加されると、変更も変更されます(ただし、これは実装の詳細です)。environ
putenv()
システムコールレベルとライブラリレベルを区別する必要があります。システムコールレベルでは、環境に関連する唯一のメカニズムは呼び出しenvp
のパラメータですexecve
。このパラメーターname=value
には、新しいプログラム環境を構成するペアが含まれると予想されます。環境は、ユーザースペースの開始コードが選択できる新しいプロセスのスタックにコピーされます。
図書館レベルでは、
environ
環境コピーを指すグローバル変数- 機能性検査
getenv()
とputenv()
修正環境 - 暗黙的に(渡す)または明示的に(パラメータを介して渡す)環境にアクセスする一連の
exec*
関数(含まれていません)execve
environ
ライブラリexec*
関数は最終的にexecve
システムコールを呼び出します。変数environ
はスタックの環境を指しません。代わりに、environ
変数が設定される前に環境がプロセスヒープにコピーされます。これは再実装の詳細です。
/proc/$$/environ
なぜ環境変化を反映できないのでしょうか?/proc/$$/environ
カーネルが提供する仮想ファイルなので、カーネルはユーザープロセスのアドレス空間の下位レベルで何が起こっているのかわかりません。カーネルは、このenviron
変数や環境を保存するためにプロセスが使用するデータ構造について知りません。