The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

在不同的作業系統下如何設定包含小數點的環境變數名稱

一般來說,我們極少會在環境變數上使用小數點( . )當成環境變數名稱來使用,但是在特定應用程式的條件下,可能被迫需要做出這樣的設定。像透過環境變數設定 .NET 應用程式的 LogLevel 就很可能會用到小數點來進行設定,本篇文章我將說明不同作業系統下的設定方式與潛在問題。

前情提要

假設我們已經安裝好 .NET 6 SDK 並用以下命令建立一個 Web 應用程式:

dotnet new web -n web1

你可以從 web1\appsettings.json 檔案看到以下內容:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

因為 .NET 預設會透過 EnvironmentVariablesConfigurationProvider 載入環境變數,作為應用程式的組態,當我們將 .NET 執行在容器中或跑在 IIS 的時候,都很容易設定環境變數來設定應用程式組態。

例如我們在應用程式執行前設定 Logging__LogLevel__Default 環境變數,將其值設定成 Warning,就可以讓整個 .NET 應用程式預設所有 LogLevelWarning 等級以上,這個等級以下的就不會輸出到記錄中。

不過,另外還有一個 Microsoft.AspNetCore 所代表的是另一個記錄類別 (Log Category),通常這裡所代表的是命名空間 (namespace),因為預設透過 ILogger<T> 注入的物件,預設記錄類別就是型別的完整名稱 (Full Name),也就是 命名空間 (Namespace) 加上 型別名稱 (Type Name)。由於 .NET 的命名空間都包含了小數點,因此你若要透過環境變數設定該參數,就一定會用到小數點當作環境變數名稱的一部分。

詳細內容請見 Logging in .NET Core and ASP.NET Core 文件說明。

問題說明與解決方案

這裡最主要的問題就是:

  1. Windows 環境變數允許出現 . (小數點) 符號
  2. Linux/macOS 的 Bash 殼層環境不允許出現 . (小數點) 符號

以下我就來說說不同作業系統的設定方法:

  1. Windows

    在 Windows 作業系統下,環境變數名稱允許小數點的,因此設定上其實沒啥問題!

    以下是 PowerShell 的設定方法:

    ${env:Logging__LogLevel__Microsoft.Hosting.Lifetime}='Debug'
    

    以下是 Command Prompt 的設定方法:

    set Logging__LogLevel__Microsoft.Hosting.Lifetime=Debug
    
  2. Linux / macOS

    如果你去看 Bash 的說明手冊 ( man bash ),會查到以下說明:

    A word consisting only of alphanumeric characters and underscores, and beginning with an alphabetic character or an underscore. Also referred to as an identifier.

    簡言之,你完全無法在 Bash 環境下設定出一個含有 . (小數點) 的環境變數名稱,就是不可能!但有少數 Shell 環境是可以的,例如有個我自己也沒用過的 rc shell!

    但是你可以在應用程式啟動之前,透過 env 工具設定出一個臨時的、含小數點的環境變數,這是在 Linux / macOS 底下唯一可以使用的方法了。以下範例:

    env "Logging__LogLevel__Microsoft.AspNetCore=Trace" dotnet run
    

期待 .NET 7 解決這個問題

由於到了 .NET 6 都還沒有 . (小數點) 字元的替代命名規則,因此目前尚無法徹底解決 Bash 無法設定名稱中帶 . (小數點) 的環境變數。不過這個問題早在 2019 年就有人提出了,預計會在 .NET 7 的時候得到解決。詳見: [Feature Request] Add a replacement for dot in EnvironmentVariablesConfigurationProvider #35989

相關連結