別のシェルインスタンスで環境変数を設定したいと思います。だから私は調査をしてみることにしました。記事を読んだ後数字~の質問~についてこれ私はそれを試してみることにした。
2つのシェルAとB(PID 420)を作成し、両方ともzsh
シェルAIで次のコマンドを実行します。
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
実行すると、シェルBのenv
FOO変数に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
シェルが初期化される前に呼び出されたためです。zsh
setenv()
gdb
setenv()
main()
bash
のはでありmain()
、その環境変数の変数をマッピングしますint main(int argc, char* argv[], char* envp[])
が、のはであり、それから変数を取得します。修正は内部では行われません(複数のシステムとこれらのポインタが指す文字列から読み取り専用)。bash
envp[]
zsh
int main(int argc, char* argv[])
zsh
environ
setenv()
environ
envp[]
それにもかかわらず、environ
シェルが始まる時点を読んだ後、それ以降はシェルは使用されなくなります(または)、使用にはsetenv()
何の効果もありません。environ
getenv()