
我知道它envsubst
会替换输入中声明的环境变量。
$ echo 'Hello $USER' | envsubst
Hello myusername
我想要的是一种替换环境变量(如果环境变量存在)的方法envsusbst
(或任何其他命令),使变量字符串保持原样。我得到的是:
$ echo 'Hello $USER $UNDEFINED_VARIABLE' | envsubst
Hello myusername
我想要的是:
$ echo 'Hello $USER $UNDEFINED_VARIABLE' | somecommand
Hello myusername $UNDEFINED_VARIABLE
答案1
如果您传递一个像$USER$PATH
to 这样的参数envsubst
,那么它只会扩展该参数中引用的那些变量。
因此,一种方法可能是以该格式传递所有当前定义的环境变量。和zsh
:
echo 'Hello $USER ${USER} $UNDEFINED_VARIABLE' |
envsubst \$${(kj:$:)parameters[(R)*export*]}
$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')"
小心泄露你的环境变量名字在 的输出中ps
。
相反,您也可以在以下位置完成整个操作perl
:
perl -pe 's{(?|\$\{([_a-zA-Z]\w*)\}|\$([_a-zA-Z]\w*))}{$ENV{$1}//$&}ge'
当心它有相同的局限性就像envsubst
那样它不会扩展类似的东西${VAR:-x}
并且会扩展$HOME
诸如\$HOME
或$$HOME
等 shell 不会扩展的内容。
答案2
您可以使用env
查看所有当前定义的环境变量,然后使用该列表仅替换这些变量。 (手册页对此不太清楚,但请参阅这个答案以供说明。)
echo 'Hello $USER $UNKNOWN' | envsubst "$(env | cut -d= -f1 | sed -e 's/^/$/')"
( 的输出env
也列出了变量的值,但envsubst
也希望看到一个前导$
,因此不幸的是,我们不能单独使用cut -d= -f1
。您也可以使用单个sed
来完成cut
工作,请参阅以前的修订版,但我更喜欢清晰度,而cut
不是微小的性能增益。)