我使用 envsubst 将环境变量替换为 Linux 中的文件。
envsubst < task-definition.json > new-task-definition.json
如何使用默认资源或使用第三方工具在 Windows 中实现此功能?
答案1
我不知道envsubst
Windows 中是否有内置命令可以替代该命令。不过,既然您已将第三方工具作为选项,我建议明网,一款面向 Windows 用户的极简 GNU 软件包。它还附带了envsubst
适用于 Windows 的实现。
赛格威也可能是一个选项。它为 Windows 提供了更完整的 GNU 工具和其他开源工具集合(例如,还附带了适用于 Windows 的 POSIX API)。它应该也有一个,envsubst
但由于我本地没有 CygWin,所以我无法确认这一点。
我会选择 MinGW,因为 CygWin 提供的额外功能(POSIX 环境)不是必需的,envsubst
但选择权在你手中(这篇文章和本文可能会帮助你做出决定)。
答案2
那里是github 上有几个这个的跨平台实现(用 go 编写),是与 envsubst 兼容,并添加一些额外的技巧。
Drone 有一个巧妙的技巧,例如改变值的大小写或进行正则表达式替换,但没有二进制版本:
https://github.com/drone/envsubst
a8m 有二进制版本,并支持默认值和后备值:
https://github.com/a8m/envsubst/releases
另外,正如@rchekaluk 所建议的,PowerShell 可以安全地扩展变量。
它使用电源外壳变量,因此如果你想使用环境变量要么必须将它们命名为${env:USERNAME}
(或$Env:UserName
)(这与 envsubst 不兼容),要么必须先将环境变量复制到 PowerShell 变量中:
Get-ChildItem Env: | Set-Variable
在 PowerShell 中扩展字符串中变量的安全方法是使用:
$ExecutionContext.InvokeCommand.ExpandString($String)
因此我们可以以大致兼容的方式将它们组合在一起:
function envsubst {
param([Parameter(ValueFromPipeline)][string]$InputObject)
Get-ChildItem Env: | Set-Variable
$ExecutionContext.InvokeCommand.ExpandString($InputObject)
}
cat template.yaml | envsubst > result.yaml
答案3
Ubuntu/Debian 中的数据包gettext-base
具有envsubst
相同的功能。
在线文档在项目envsubst
中gettext
。
答案4
使用 PowerShell 的 Windows 等效 Envsubst
Windows 中没有envsubst
内置的直接替代品,但你可以使用 PowerShell 实现类似的功能。这是一个批处理脚本,你可以使用它来替换${VARIABLE_NAME}
文件中格式的环境变量引用:
@echo off
setlocal
powershell -NoProfile -Command "$content = Get-Content -Path inputfile.txt -Raw; $matches = [regex]::Matches($content, '\$\{([^}]+)\}'); foreach ($match in $matches) { $varName = $match.Groups[1].Value; $replacement = (Get-Item -LiteralPath \"Env:$varName\").Value; $content = $content.Replace($match.Value, $replacement); } Set-Content -Path outputfile.txt -Value $content;"
endlocal
您需要将inputfile.txt
和修改outputfile.txt
为适当的路径。执行时,脚本会将${VARIABLE_NAME}
中的 实例替换inputfile.txt
为相应环境变量的值,并将结果输出到outputfile.txt
。
这种方法使用本机 PowerShell 功能,不依赖第三方工具或实用程序,使其成为 Windows 用户的可移植解决方案。
以下是脚本的逐节分解:
1. 批处理脚本启动和上下文设置
@echo off
此命令可抑制批处理文件中执行命令时的回显或显示。
setlocal
此命令可确保脚本中的环境更改(如变量赋值)仅限于批处理文件。如果没有setlocal
,任何环境变量更改都会影响启动批处理文件的命令 shell。
2. PowerShell 执行
powershell -NoProfile -Command "..."
这将从批处理脚本中调用 PowerShell 解释器。该-NoProfile
标志确保不加载任何用户特定的配置文件或配置,从而保证环境的一致性。该-Command
标志指定将执行的 PowerShell 命令,用双引号括起来。如果命令有多行,批处理脚本将假定每行都是单独的批处理函数,而不是 PowerShell 命令的一部分。所以它们都在一行上。
3.读取输入文件
$content = Get-Content -Path inputfile.txt -Raw;
此行使用Get-Content
cmdlet 将整个内容读inputfile.txt
入$content
变量。该-Raw
参数确保将整个文件读取为单个字符串,而不是行数组。
4. 查找环境变量引用的匹配项
$matches = [regex]::Matches($content, '\$\{([^}]+)\}');
这里我们使用 .NET 的正则表达式类来查找与$content
模式匹配的所有实例${VARIABLE_NAME}
。找到的每个匹配项都将存储在$matches
变量中。
5. 迭代匹配并执行替换
foreach ($match in $matches) { ... }
这是一个循环,遍历上一步中找到的每个匹配项。
$varName = $match.Groups[1].Value;
我们从每个匹配中提取变量名称。[1]
指的是正则表达式中的第一个捕获组,它对应于VARIABLE_NAME
。
$replacement = (Get-Item -LiteralPath \"Env:$varName\").Value;
对于每个变量名,此行从环境变量中获取其对应的值。
$content = $content.Replace($match.Value, $replacement);
在$content
字符串中,此行${VARIABLE_NAME}
用其对应的环境变量值替换模式。
6.将修改的内容写入输出文件
Set-Content -Path outputfile.txt -Value $content;
这$content
将把修改后的内容(替换了变量)写入outputfile.txt
。
7. 关闭本地上下文
endlocal
此批处理命令将环境恢复到脚本启动之前的状态,确保脚本中所做的任何变量更改或修改都不会影响调用 shell。
这些部分共同创建了一个脚本,可以${VARIABLE_NAME}
使用 PowerShell 在 Windows 机器上用相应的环境变量值替换文件中的模式。希望这对您有所帮助。