Envsubst 有转义字符吗?

有没有办法可以防止 envsubst代替 $VARIABLE? 例如,我可以期待这样的事情:

export THIS=THAT
echo "dont substitute \\\$THIS" | envsubst

让它回来

dont substitute $THIS

但我却得到了

dont substitute \THAT

有什么逃脱角色吗?

27448 次浏览
export DOLLAR='$'


export THIS=THAT
echo '${DOLLAR}THIS' | envsubst

或者更明确一点:

export THIS=THAT
echo '${DOLLAR}THIS' | DOLLAR='$' envsubst

如果你给 envsubst一个变量列表,它 只有替换这些变量,忽略其他替换。我不太清楚它是如何工作的,但是下面这些东西似乎可以满足你的需要:

$ export THIS=THAT FOO=BAR
$ echo 'dont substitute $THIS but do substitute $FOO' | envsubst '$FOO'
dont substitute $THIS but do substitute BAR

请注意,$THIS被单独留下,但是 $FOOBAR取代。

在我的例子中,我只想转义那些还没有定义的 var:

envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')"

如果只有一个或两个变量你不想展开,你可以通过暂时将它们设置为自己的名字来将它们列入白名单,如下所示:

$ echo 'one $two three $four' | four='$four' envsubst
one  three $four

在这里,将 $four变量替换为 $four,实际上使其保持不变。

我的解决办法如下:

原始模板:

$change_this
$dont_change_this

编辑模板:

$change_this
§dont_change_this

现在你可以处理:

envsubst < $template | sed -e 's/§/$/g'

这依赖于字符 §不会出现在模板的其他地方。您可以使用任何其他字符。

$ echo $SHELL
/bin/bash
$ echo \$SHELL
$SHELL
$ echo \$SHELL | envsubst
/bin/bash
$ echo \$\${q}SHELL | envsubst
$SHELL

这样做 $$允许您添加一个 $字符。然后只是“替换”不存在的变量(在这里我使用 ${q},但可以是一些更有意义的东西,如 ${my_empty_variable},你会得到你需要的。

就像段落解决方案一样——您需要一些特殊的东西——在这里... 一个不存在的变量,比起在模板上执行额外的 sed,我更喜欢它。

“转义”某些环境变量替换的另一种方法是使用默认值赋值(或任何其他变量处理) ,因为 envsubst 不会替换以下内容:

$ export two=2
$ echo 'one $two three ${four:-}' | envsubst
one 2 three ${four:-}

第四个 envar 不被替换,而在其输出中使用缺省值的处理仍然存在。但是这并不重要,因为如果没有设置变量及其设置时的值,稍后处理该行仍然不会产生任何结果。

下面是我使用的一个替代方案,因为它可以为一个程序节省安装整个 gettext包的时间。我有这个 awk 脚本,我调用 envtmpl,它会把任何看起来像 \{\{ENV-VAR}}的环境变量换成 ENV-VAR的值

#! /usr/bin/awk -f
{ for (a in ENVIRON) gsub("\{\{" _ a _ "}}",ENVIRON[a]); print }

那么

$ echo "My shell '\{\{SHELL}}' is cool" | envtmpl
My shell '/bin/bash' is cool

正如你所看到的,如果 \{\{}}不是你喜欢的,它真的每个改变,这个脚本工程与 busyboxawk的罚款。

它不会成为世界上最快的解决方案,但它真的很容易实现,我大多数情况下运行它来准备配置文件,所以速度是相当无关紧要的。

警告: 唯一的 少校之间的区别是,这将 没有改变变量没有值存在。也就是说,\{\{HAS-NO-VALUE}}将完全保持原样,而 envsubst将删除这些内容(将它们替换为空白)。

如果需要,可以通过在 awk中添加更多代码来修复这个问题。

我的做法是

export DONT_CHANGE_THIS=\${DONT_CHANGE_THIS}
envsubst < some-template.yml > changed.yml

因此,它将尝试用 ${ var }替换 ${ var } ,作为输出,您将得到原样打印的 ${ var }

我用了转义字符

MYENVVAR="\${MYENVVAR}"
export MYENVVAR
envsubst #whatever you want

然后重置成我真正想要的

MYENVVAR="my value"
export MYENVVAR

我只是将其他答案的一部分连接起来,创建了一行程序,用 $前缀的 vars 替代 $$,但是忽略了 $$:

回显“ $TEST; $$l”> TEST _ FILE 猫测试 _ 文件 测试 出口测试 = 1 Cat TEST _ FILE | sed-e’s/$$//g’| envsubst | sed-e’s//$/g’ # 1; $l