在 Linux 中,envsubst 在 Windows 中的对应版本是什么?

在 Linux 中,envsubst 在 Windows 中的对应版本是什么?

我使用 envsubst 将环境变量替换为 Linux 中的文件。

envsubst < task-definition.json > new-task-definition.json

如何使用默认资源或使用第三方工具在 Windows 中实现此功能?

答案1

我不知道envsubstWindows 中是否有内置命令可以替代该命令。不过,既然您已将第三方工具作为选项,我建议明网,一款面向 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相同的功能。

在线文档在项目envsubstgettext

答案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-Contentcmdlet 将整个内容读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 机器上用相应的环境变量值替换文件中的模式。希望这对您有所帮助。

相关内容