私はx86_64 GNU / Linuxを使用しています。bash
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
system("set > setc"); // A subset of `$ set`
return 0;
}
setcファイルにが含まれていることがわかります$ set
。
シェル(親プロセス)が子プロセスに提供するものと提供しないことをどのように決定するのか疑問に思います。
子プロセスにさらに環境変数を提供するにはどうすればよいですか?どのように制御できますか?
答え1
シェル組み込みは、set
環境にエクスポートされた変数だけでなく、すべての変数を表示します。
環境に変数を追加するには、export variablename
シェルで実行します。
答え2
後で環境変数があるプログラムから別のプログラムに転送される方法は次のとおりです。execve
ディスクから新しいプログラムイメージをロードするシステムコール。 (画像は現在のプログラムを置き換えます。別のシステムコールがあります。fork
、現在のプログラム機能(system
Combineなどfork
)execve
や他のシステムコールをコピーしてサブプロセスを開始します。 )この低レベルでは、プログラムは必要なものを後続のプログラムに渡すことができます。
ただし、ほとんどのプログラムは起動時に受信される環境を単に渡します。たとえばsystem
、プログラムの初期環境に初期化されたグローバル変数を読み取るライブラリ関数。たとえば、putenv
プログラムに環境を変更するように特別に設計されたコードが含まれていない場合、その環境は子として送信されます。プロセス。
テストでシェルコマンドを使用しました。set
。このコマンドは、環境変数の親セットであるシェル変数をリストします。シェルは、すべての環境変数をシェルプログラミング言語の変数として表示します。さらに、より多くの変数を定義できます。組み込みコマンドexport
シェル変数の名前を引数として使用し、変数をエクスポート済みとしてマークします。エクスポートされたとマークされた変数は、子プロセスの環境に追加されます。
対話型シェルには通常、エクスポートされていないシェル変数がたくさんあります。新しくリリースされた非対話型シェルの数は少なくなります。これがsystem("set")
インタラクティブシェルで見られるよりも少ない変数を見ることができる理由です。環境変数(コマンドを使用するかenv
引数なし)を見ると、export
同じ変数(またはシェルに応じてより多くの変数)を見つけることができます。
答え3
読んだ後、man bash
全体像が見えます。質問を投稿する前にその人の記事を読んでいたら!しかし、上記の答えの1つは間違っているようで、もう1つは明確ではありません。だから:
シェルには、呼び出し時にシェルが継承するオープンファイル、ファイル生成モードマスク、環境のシェル親から継承されたシェルパラメータなどで構成される実行環境があります。 (詳細については、「man bash
コマンド実行環境」のセクションを参照してください。)引数なしで呼び出されると、シェル環境に存在するすべての変数の値(名前=値の形式)を吐き出します。 (シェル環境の出力とコンポーネントを参照してください。)declare
set
set
declare
これで、組み込み機能やシェル機能ではなく単純なコマンドを実行したい場合は、分離実行環境は、シェルのオープンファイル、ファイル生成モードマスク、エクスポート用にマークされたシェル変数と関数(シェル環境の変数と関数のサブセット)などで構成されます。 Gillesが上記の回答で述べたように、このコマンドを分岐しようとすると、「プログラムに環境を変更するように特別に設計されたコードが含まれていない場合、その環境は子プロセスに送信されます。」
したがって、上記のプログラムを実行しようとすると、プログラムはシェル環境のサブセットを受け取ります。その後、system("set> setrc")と言うと、system()は子プロセス(ただしこれはシェルです)を生成し、子シェルはを実行しますset > setrc
。これを実行すると、プログラムはその環境(親シェル環境の単純化されたバージョン)を子プロセス(シェル実行set
)に転送します。実行されるとset > setrc
、親シェル環境の簡略化されたバージョンである呼び出しシェル環境内のすべての変数の値(名前=値の形式)が印刷されます。これがsetrcの内容が減った理由です。
これで、Bashのコマンドに渡される環境を制御する方法:
Bashがコマンドに渡すパラメータとexport
関数を制御するためにおよびを使用できますdeclare -x
。 (man bash
環境セクション。)
export
他の人が述べたように、env
明確にするために:(export
引数env
なしで)シェルの環境ではなく、サブプロセス(またはコマンド)に渡される環境を印刷し、set
すべてのdeclare
変数を吐き出します。シェル環境。そのため、$VAR_NAME(内部set
または出力declare
でなくても内部env
または出力に存在するすべての変数export
)をエコーできます。