web-dev-qa-db-ja.com

Cで環境変数を設定する

Cを使用してLinuxで環境変数を設定する方法はありますか?

setenv()putenv()を試しましたが、それらは私のために機能していないようです。

31
iman453

ここで思い切って推測しますが、これらの関数が機能しないように見える通常の理由は、機能しないためではなく、ユーザーが環境変数の仕組みを実際に理解していないためです。たとえば、このプログラムがある場合:

int main(int argc, char **argv)
{
  putenv("SomeVariable=SomeValue");
  return 0;
}

そして、シェルから実行しますが、シェルの環境は変更されません-子プロセスがそれを行う方法はありません。そのため、環境を変更するシェルコマンドがビルトインであり、単にシェルを実行するのではなく、シェルに追加する変数設定を含むスクリプトをsourceする必要があります。

47
Carl Norum

UNIXプログラムは、それを開始するプロセスとは別のプロセスで実行されます。これは「子」プロセスです。

プログラムが起動されると(コマンドラインまたはその他の方法で)、システムは(おおよそ)親プロセスのコピーである新しいプロセスを作成します。そのコピーには、親プロセスの環境変数が含まれます。これは、子プロセスが親の環境変数を「継承」するメカニズムです。 (これは、主にここでの他の答えが言ったことです)

つまり、プロセスはeverのみown環境変数を設定します。

他の人は、現在のプロセスで環境変数を設定する方法としてシェルスクリプトを使用することに言及していますが、現在の(シェル)プロセスで変数をプログラムで設定する必要がある場合は、少し間接的な方法があります。

このことを考慮:

% cat envs.c
#include <stdio.h>
int main(int argc, char**argv)
{
    int i;
    for (i=1; i<argc; i++) {
        printf("ENV%d=%s\n", i, argv[i]);
    }
}
% echo $ENV1

% ./envs one two
ENV1=one
ENV2=two
% eval `./envs one two`
% echo $ENV1
one
% 

組み込みのevalは、引数がシェルプロンプトで入力されたかのように引数を評価します。これはshスタイルの例です。 cshスタイルのバリアントは演習として残しておきます!

10
Norman Gray

Setenv()/ putenv()によって設定された環境変数は、これらの機能を実行したプロセスに対して設定され、それによって起動されたプロセスによって継承されます。ただし、プログラムを実行したシェルにはbroadcastedされません。

setenv()のラッパーが機能しない理由

5
karlphillip

環境ブロックはプロセスローカルであり、子プロセスにコピーされます。したがって、変数を変更した場合、新しい値は、変更後のプロセスと子プロセスのみに影響します。確実に起動したシェルは変更されません。

1
Ben Voigt