PowerShell 如何讀取解析 Env/Properties 檔案
實作做的功能包含了
- 自動讀取 “.env”, “.env.development”, “.env.production” 三個檔案,優先順序是後面覆蓋前面,同檔案間優先順序也是後面覆蓋前面
- 支援擴充功能使用斜線換行
- 支援擴充功能雙引號解析 PowerShell 變數
為什麼要拆分這麼多env檔案主要是兩個觀點
- 把連接資訊放在“.env.production”中避免部署設置時不小心動到連接資訊。
- 拆分development跟production,僅共用.env檔案這樣可以很好的區分開發機跟生產環境
範例 .env
A1=" AAA
A2= AAA "
B1=" AAA "
B2=' AAA '
C1= \
arr1,\
arr2
D1="$($env:USERNAME)"
D2='$($env:USERNAME)'
Z=\
A\
B\
C\
D\
讀取用函式
ConvertFrom-Env.ps1
# 轉換 Env 文件
function ConvertFrom-Env {
param (
[string[]]$EnvFiles = @(".env", ".env.development", ".env.production"),
[System.Text.Encoding]$Encoding = [System.Text.Encoding]::Default
)
# 使用有序字典保持讀取的順序
$envVariables = [Ordered]@{}
function ProcessLine {
param (
[string]$line
)
# 忽略註釋行
if ($line -and -not $line.StartsWith("#")) {
if ($line -match "^\s*([^#=]+?)\s*=\s*(.*)$") {
$key = $matches[1].Trim()
$value = $matches[2]
if ($value -match '^"(.+)"$') {
# 處理雙引號包圍的值並展開字符串
$value = $matches[1] -replace '\\n', "`n" -replace '\\r', "`r" -replace '\\t', "`t"
$value = $ExecutionContext.InvokeCommand.ExpandString($value)
} elseif ($value -match "^'(.+)'$") {
# 處理單引號包圍的值
$value = $matches[1]
} else {
$value = $value.Trim()
}
# 將解析後的鍵值對加入字典
$envVariables[$key] = $value
}
}
}
# 遍歷所有指定的文件
foreach ($file in $EnvFiles) {
if (Test-Path $file) {
try {
$reader = New-Object System.IO.StreamReader -ArgumentList $file, $Encoding
try {
$currentLine = ''
while ($null -ne ($line = $reader.ReadLine())) {
$trimmedLine = $line.Trim()
if ($trimmedLine.EndsWith('\')) {
# 跨行值的處理
$currentLine += $trimmedLine.TrimEnd('\').TrimEnd()
continue
} else {
$currentLine += $trimmedLine
}
ProcessLine -line $currentLine
$currentLine = ''
}
# 處理跨行結尾在最一行時沒被處理的剩餘值
if ($currentLine) { ProcessLine -line $currentLine }
} finally {
$reader.Close()
}
} catch {
Write-Warning "無法讀取文件 '$file': $_"
}
}
} # $envVariables = [PSCustomObject]$envVariables
return $envVariables
} ConvertFrom-Env
代碼開源於此: hunandy14/ConvertFrom-Env (github.com)
沒有留言:
張貼留言