プロセスは、「サブシェル」で実行されているBashで実行されますか?

プロセスは、「サブシェル」で実行されているBashで実行されますか?

Bashシェルで実行可能ファイル(a.outなど)を実行すると、実行可能ファイルは一種の「サブ」シェルで実行されていますか?つまり、入力しているシェルとは違いますか?

たとえば、私の問題を説明しようとします。次のプログラムは、環境変数の値を取得して印刷し、変更して再インポートして印刷します。

#include <iostream>
#include <string>
#include <cstdlib>
int main( int argc, char* argv[] )
{
  std::string str( getenv( "FOO" ) );
  std::cout << str << std::endl;
  setenv( "FOO", "bar", 1 );
  str = getenv( "FOO" );
  std::cout << str << std::endl;
  return 0;
}

次に、Bash プロンプトで次のコマンドを実行したときに出力される内容を確認します。

>unset FOO && export FOO=foo && printf "$FOO\n" && ./a.out && printf "$FOO\n"
foo
foo
bar
foo
>
>unset FOO && export FOO=baz && printf "$FOO\n" && ./a.out && printf "$FOO\n"
baz
baz
bar
baz

FOOそのため、実行可能ファイルからインポートできるようにエクスポートしています。わかりました。実行ファイルの出力には、環境変数が変更されていることが表示されます。

しかし、最終的にはprintf "$FOO\n"プリラン値が印刷されます。実行ファイルがコマンドを入力した場所と「異なる環境」で実行されているからですか?

ベストアンサー1

Unixでは、それぞれプロセス環境には独立したコピーがあります。プロセスは、fork()親プロセスの環境をコピーして作成されたときに初期環境を取得します。

したがって、a.outを呼び出す前にシェル環境に変数を追加すると、a.outはそれを表示します(a.outが変数を含むシェル環境のコピーを受け取るため)。

a.out が環境を変更すると、シェル環境ではなく a.out の環境が変更されます。 a.outが別のプログラムを呼び出すと(たとえば、を使用してsystem())、そのプログラムはa.out環境のコピーを取得するため、変更された環境が表示されます。

a.out が終了すると、対応する環境変数は削除されます。もちろん、子プロセスが実行されている場合、そのプロセスのコピーは終了するまで保持されます。

a.out が継続して実行されている間 (たとえば、バックグラウンドで)、シェルで環境を変更すると、a.out &a.out に変更は表示されません。環境は、プロセスが作成されたときにのみコピーされます。

[これは一般的です。システムexecveコールを使用すると、親プロセスからコピーされた環境ではなく、指定された環境を使用してプログラムを実行できます。 ]

おすすめ記事