替换文本中的环境变量(如果存在)

Far*_*igo 6 linux shell bash

我知道envsubst替换输入中声明的环境变量。

$ echo 'Hello $USER' | envsubst
Hello myusername
Run Code Online (Sandbox Code Playgroud)

我想要的是一种替换环境变量的方法,如果它以其他方式存在envsusbst(或任何其他命令),则将变量字符串保持原样。我得到的是:

$ echo 'Hello $USER $UNDEFINED_VARIABLE' | envsubst
Hello myusername
Run Code Online (Sandbox Code Playgroud)

我想要的是:

$ echo 'Hello $USER $UNDEFINED_VARIABLE' | somecommand
Hello myusername $UNDEFINED_VARIABLE
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 3

如果您传递一个像$USER$PATHto这样的参数envsubst,那么它只会扩展该参数中引用的那些变量。

因此一种方法可能是以该格式传递所有当前定义的环境变量。和zsh

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst \$${(kj:$:)parameters[(R)*export*]}
Run Code Online (Sandbox Code Playgroud)
  • $parameters是一个特殊的关联数组,它将变量名称映射到其类型
  • $parameters[(R)*export*]扩展到关联数组中值包含 的所有元素export
  • k参数扩展标志,返回而不是值
  • j:$:将这些元素连接起来$,并在开头添加一个。

对于其他 shell,您可以随时返回perl以获取该列表:

echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
  envsubst "$(perl -e 'print "\$$_" for grep /^[_a-zA-Z]\w*$/, keys %ENV')"
Run Code Online (Sandbox Code Playgroud)

请注意,两者都会在 的输出中公开您的环境变量名称ps

相反,您也可以在以下位置完成整个操作perl

perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
Run Code Online (Sandbox Code Playgroud)

请注意,它具有相同的局限性envsubst,因为它不会扩展诸如 之类的东西${VAR:-x},并且会扩展$HOME诸如\$HOME$$HOME之类的东西,而 shell 不会这样做。