envsubst:未设置变量的默认值

chr*_*hrx 8 linux bash environment-variables

我有一个input.json像以下一样的json文件:

{
  "variable" : "${ENV_VAR}"
}
Run Code Online (Sandbox Code Playgroud)

当然,我可以从bash中调用envsubst,如下所示:

$ export ENV_VAR=myvalue
$ envsubst < input.json > output.json
$ cat output.json
{
  "variable" : "myvalue"
}
Run Code Online (Sandbox Code Playgroud)

现在,我希望我可以在input.json中为ENV_VAR未设置的情况设置变量的默认值,如下例所示,不幸的是,在下面的示例中可以看到它不起作用:

$ cat input.json
{
  "variable" : "${ENV_VAR:=defaultvalue}"
}
$ export ENV_VAR=newvalue
$ envsubst < input.json > output.json
$ cat output.json
{
  "variable" : "${ENV_VAR:=defaultvalue}"
}
$ unset ENV_VAR
$ envsubst < input.json > output.json
$ cat output.json
{
  "variable" : "${ENV_VAR:=defaultvalue}"
}
Run Code Online (Sandbox Code Playgroud)

有什么好奇的,如果我执行envsubst,如下例所示(不涉及输入文件),它的工作原理

$ export ENV_VAR=myvalue
$ echo "value is ${ENV_VAR:=defaultvalue}" | envsubst
value is myvalue
$ unset ENV_VAR
$ echo "value is ${ENV_VAR:=defaultvalue}" | envsubst
value is defaultvalue
Run Code Online (Sandbox Code Playgroud)

文件的问题在哪里?

Rob*_*479 12

根据man envsubst,envsubst只会以${VAR}或的形式替换对环境变量的引用$VAR.${VAR:-default}不支持特殊的shell功能.您唯一能做的就是(重新)定义envsubst调用环境中的所有变量,并分配本地默认值(如果它们丢失):

ENV_VAR="${ENV_VAR:-defaultvalue}" \
OTHER_VAR="${OTHER_VAR:-otherdefault}" \
envsubst < input.json > output.json
Run Code Online (Sandbox Code Playgroud)

注意,这实际上是单个命令行分成多行,每行以行继续结束\.前两行是变量赋值,仅envsubstr在最后一行中执行的命令的环境中有效.发生的事情是,shell将创建一个执行命令的环境(就像它一直这样).该环境最初是当前shell环境的副本.在该新环境中,ENV_VAR并为其OTHER_VAR分配扩展表达式的值,该值${VAR:-default}基本上扩展为default除非VAR已定义且具有非空值.envsubst执行该命令,接收文件input.json作为标准输入并将其标准输出重定向到output.json(两者都由shell完成).在命令执行之后,shell删除返回其原始环境的命令环境,即局部变量赋值不再有效.

除非您自己实现程序,否则无法从JSON文件内部定义默认值,或者使用其他可以执行此操作的工具.

您可以执行以下操作,但不建议您:

eval echo "$(cat input.json)" > output.json
Run Code Online (Sandbox Code Playgroud)

它将读input.json入一个字符串,而不是eval命令echo <string>,就好像它是字面上的类型一样,这意味着${VAR:-default}在传递字符串之前,任何嵌入的东西都应该由shell扩展echo.但是,任何其他嵌入式shell功能也将被评估,这会带来巨大的安全风险.


mas*_*ash 8

我正在使用https://github.com/a8m/envsubst,它比原始 gettext envsubst 具有增强功能,模板文件中的表达式支持默认值。

自述文件中的示例可以正常工作。

echo 'welcome $HOME ${USER:=a8m}' | envsubst
Run Code Online (Sandbox Code Playgroud)