一般來說,我們極少會在環境變數上使用小數點( .
)當成環境變數名稱來使用,但是在特定應用程式的條件下,可能被迫需要做出這樣的設定。像透過環境變數設定 .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 應用程式預設所有 LogLevel
為 Warning
等級以上,這個等級以下的就不會輸出到記錄中。
不過,另外還有一個 Microsoft.AspNetCore
所代表的是另一個記錄類別 (Log Category),通常這裡所代表的是命名空間 (namespace),因為預設透過 ILogger<T>
注入的物件,預設記錄類別就是型別的完整名稱 (Full Name),也就是 命名空間 (Namespace) 加上 型別名稱 (Type Name)。由於 .NET 的命名空間都包含了小數點,因此你若要透過環境變數設定該參數,就一定會用到小數點當作環境變數名稱的一部分。
詳細內容請見 Logging in .NET Core and ASP.NET Core 文件說明。
問題說明與解決方案
這裡最主要的問題就是:
- Windows 環境變數允許出現
.
(小數點) 符號
- Linux/macOS 的 Bash 殼層環境不允許出現
.
(小數點) 符號
以下我就來說說不同作業系統的設定方法:
-
Windows
在 Windows 作業系統下,環境變數名稱是允許小數點的,因此設定上其實沒啥問題!
以下是 PowerShell 的設定方法:
${env:Logging__LogLevel__Microsoft.Hosting.Lifetime}='Debug'
以下是 Command Prompt 的設定方法:
set Logging__LogLevel__Microsoft.Hosting.Lifetime=Debug
-
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
相關連結