編集する

編集する

別のシェルインスタンスで環境変数を設定したいと思います。だから私は調査をしてみることにしました。記事を読んだ後数字~の質問~についてこれ私はそれを試してみることにした。

2つのシェルAとB(PID 420)を作成し、両方ともzshシェルAIで次のコマンドを実行します。

sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach

実行すると、シェルBのenvFOO変数にbar値が設定されていることがわかります。これにより、シェルB環境でFOOが正常に初期化されたと考えられます。ただし、FOOを印刷しようとすると、まだ設定されていないことを示す空白行が表示されます。私にはここに矛盾があるように感じられる。

これは私のArch GNU / LinuxシステムとUbuntu VMでテストされました。また、bash変数が環境に表示されない場合でもこれをテストしました。残念ながら、シェルがビルド時に環境のコピーをキャッシュし、そのコピーのみを使用した場合(リンクされた質問の1つで提案)、意味があります。zsh変数が表示される理由はまだ答えられません。

出力がecho $FOO空の理由は何ですか?


編集する

コメントにこれを入力した後、もう少しテストすることにしました。結果を下表に示す。最初の列はFOO変数が注入されたシェルです。最初の行にはコマンドが含まれており、その出力は下から見ることができます。変数はFOO以下を使用して注入されましたsudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'。 zsh:特定のコマンドzsh -c '...'もbashを使用してテストされました。結果は同じであり、簡潔にするために、対応する出力は省略される。

アーチ GNU/Linux, zsh 5.3.1, bash 4.4.12(1)

|      |  env | grep FOO  | echo $FOO |  zsh -c 'env | grep FOO'  |  zsh -c 'echo $FOO'  |         After export FOO          |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh  |  FOO=bar         |           | FOO=bar                   | bar                  | No Change                         |
| bash |                  | bar       |                           |                      | Value of FOO visible in all tests |

Ubuntu 16.04.2 LTS、zsh 5.1.1、bash 4.3.48(1)

|      |  env | grep FOO  | echo $FOO |  zsh -c 'env | grep FOO'  |  zsh -c 'echo $FOO'  |         After export FOO          |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh  |  FOO=bar         |           | FOO=bar                   | bar                  | No Change                         |
| bash |                  | bar       |                           |                      | Value of FOO visible in all tests |

上記は、結果が分布に依存しないことを示唆しているようです。これは私にもはや何も知らせず、zsh変数bash設定が異なるように扱われるだけです。また、export FOOこのコンテキストではシェルによって大きく異なる動作があります。このテストが他の人にも役立つことを願っています。

ベストアンサー1

getenv()ほとんどのシェルは// setenv()APIを使用しませんputenv()

起動時に受け取るすべての環境変数に対してシェル変数を生成します。これは、追加情報(たとえば、変数をエクスポートしたか読み取り専用であるか)を渡す必要がある内部構造に格納されます。これを達成するためにlibcを使用することはできませんenviron

また、このため、コマンドを実行するのではなく、execlp()直接execvp()システムコールを呼び出して、エクスポートされた変数のリストに基づいて配列を計算しますexecve()envp[]

したがって、gdbシェルの内部変数テーブルにエントリを追加するか、コードを解釈してexport VAR=valueテーブル自体を更新するために正しい関数を呼び出す必要があります。

とを呼び出すときに違いが表示されるのは、入力したときなど、bashシェルが初期化される前に呼び出されたためです。zshsetenv()gdbsetenv()main()

bashのはでありmain()、その環境変数の変数をマッピングしますint main(int argc, char* argv[], char* envp[])が、のはであり、それから変数を取得します。修正は内部では行われません(複数のシステムとこれらのポインタが指す文字列から読み取り専用)。bashenvp[]zshint main(int argc, char* argv[])zshenvironsetenv()environenvp[]

それにもかかわらず、environシェルが始まる時点を読んだ後、それ以降はシェルは使用されなくなります(または)、使用にはsetenv()何の効果もありません。environgetenv()

おすすめ記事