developer's diary

最近はc#のエントリが多いです

c# ( dotnetcore ) で 環境変数を書き込む は利用しない方が良い

前回の記事

前回の記事では環境変数を読み込む方法をエントリしました。

mitsugeek.net

今回は環境変数を書き込む方法をエントリなんですが、環境変数はOSに依存するため、利用しない方が良いようです。

そもそも環境変数はどのような時に使うのでしょうか?

The Art of UNIX Programming (アスキードワンゴ)10.4.3環 境変数をいつ使うべきか(P.272)に指針が書かれています。

  • 同じドットファイルを共有する複数のコンテキス トで値が変わる場合や、親プロセスが複数の子プロセスに情報を渡さなければならない場合
  • 値がドットファイルで管理するにはまちまちに過ぎるが、起動ごとに変わるわけではない場合
  • コマンド行の起動の仕方は変えないで、プロセス固有の特別設定を表現しなければならない場合

では早速使ってみましょう。

Environment.SetEnvironmentVariable を使う

using System;

namespace example_set_environment
{
    class Program
    {
        static void Main(string[] args)
        {
            // 環境変数の設定
            Environment.SetEnvironmentVariable("EXAMPLE_PROCESS_ENV", "test process", EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("EXAMPLE_USER_ENV", "test user", EnvironmentVariableTarget.User);
            Environment.SetEnvironmentVariable("EXAMPLE_MACHINE_ENV", "test machine", EnvironmentVariableTarget.Machine);

            // 設定した環境変数の読み込み
            Console.WriteLine("EXAMPLE_PROCESS_ENV:" + Environment.GetEnvironmentVariable("EXAMPLE_PROCESS_ENV"));
            Console.WriteLine("EXAMPLE_USER_ENV:" + Environment.GetEnvironmentVariable("EXAMPLE_USER_ENV"));
            Console.WriteLine("EXAMPLE_MACHINE_ENV:" + Environment.GetEnvironmentVariable("EXAMPLE_MACHINE_ENV"));
        }
    }
}

結果

EXAMPLE_PROCESS_ENV:test process
EXAMPLE_USER_ENV:
EXAMPLE_MACHINE_ENV:

どうも、EnvironmentVariableTarget.UserとEnvironmentVariableTarget.Machineの場合に、出力されませんでした。

親プロセスで設定した環境変数は生きているのか?

EnvironmentVariableTarget.Processは設定できるようなので、確認してみましょう。

using System;

namespace example_get_environment
{
    class Program
    {
        static void Main(string[] args)
        {
            // 環境変数の設定
            Environment.SetEnvironmentVariable("EXAMPLE_PROCESS_ENV", "test process", EnvironmentVariableTarget.Process);
        }
    }
}
pc:netcoreapp3.1 mitsugi$ dotnet example_set_environment.dll
pc:netcoreapp3.1 mitsugi$ echo $EXAMPLE_PROCESS_ENV

EnvironmentVariableTarget.Processで設定した環境変数は、 プロセスの終了後は消えてしまうため、shellで表示は出来ません。

なので、親プロセスが複数の子プロセスに情報を渡さなければならない場合の利用シチュエーションでは使えません。 ※windowsでは使えると思いますが、macでは少なくとも利用できませんでした。

調べてみる

github.com

github.com

documentに記載されていました

docs.microsoft.com

f:id:mitsugi-bb:20200821064426p:plain
Unix ベースのシステム上の .NET 実装では、プロセス環境ブロックの変数のみがサポートされます

結論

環境変数の書込は利用しない方が良い。

参考書籍