仅用 envsubst 替换特定变量

仅用 envsubst 替换特定变量

我正在尝试通过执行环境变量替换envsubst,但我只想替换特定变量。

从文档中我应该能够告诉envsubst只替换某些变量,但我无法做到这一点。

例如,如果我有一个文件包含:

VAR_1=${VAR_1}
VAR_2=${VAR_2}

我应该如何执行envsubst,以便它只替换对 的引用${VAR_1}

答案1

根据手册页:

envsubst [OPTION] [SHELL-FORMAT]

如果给出了 SHELL-FORMAT,则仅替换 SHELL-FORMAT 中引用的那些环境变量;否则,标准输入中出现的所有环境变量引用都将被替换。

SHELL-FORMAT 字符串在哪里“引用 shell 变量的字符串,格式为$variable[ ${variable}...] 变量名称必须仅包含字母数字或下划线 ASCII 字符,不能以数字开头且非空;否则此类变量引用将被忽略。”


请注意,${VAR:-default}不支持该格式。我提到这里一些支持它以及其他功能的替代方案。


无论如何,回到gettext envsubst
因此,必须以envsubstshell 格式字符串将相应的变量名称传递给(显然,它们需要转义/引用以便按字面传递给envsubst)。例子:

输入文件例如infile

VAR1=${VAR1}
VAR2=${VAR2}
VAR3=${VAR3}

和一些值,例如

export  VAR1="one" VAR2="two" VAR3="three"

然后运行

envsubst '${VAR1} ${VAR3}' <infile

或者

envsubst '${VAR1},${VAR3}' <infile

或者

envsubst '${VAR1}
${VAR3}' <infile

输出

VAR1=one
VAR2=${VAR2}
VAR3=three

或者,如果您更喜欢反斜杠:

envsubst \$VAR1,\$VAR2 <infile

产生

VAR1=one
VAR2=two
VAR3=${VAR3}

为了避免自定义设置变量泄漏到执行 shell 的环境中,而不是导出这些变量,一些贝壳,例如重击允许在命令前加上前缀变量赋值。这样分配的值只会用于命令的执行,不会影响之后的 shell 环境:

export VAR1="one" VAR2="two" VAR3="three"

# ...

VAR1="number 1" VAR3="numero 3" envsubst '${VAR1} ${VAR3}' <infile

# output:
# VAR1=number 1
# VAR2=${VAR2}
# VAR3=numero 3

echo "VAR1=${VAR1}"
echo "VAR2=${VAR2}"
echo "VAR3=${VAR3}"
# output shows that the original environment was preserved:
# VAR1=one
# VAR2=two
# VAR3=three

答案2

虽然与 docker 有关,但该实用程序envplate应该可以完成这项工作https://github.com/kreuzwerker/envplate

来自自述文件:

使用环境键对配置文件进行简单模板化。对此类键的引用可以在任意配置文件中声明为:

${key} 或

${key:-默认值}

gnutext 的 envsubst 仅替换${key};如果缺失则替换为''.

答案3

不幸的是“导出”是强制性的,否则它将无法工作。这是一个例子。

首先,输入文件。请注意,我只想更改 NGINX_HOST 和 NGINX_PORT,不想触及输入文件中的其他变量,例如“$uri”。

$ egrep 'server_name|listen|try_files' nginx-default.conf.template 
  server_name ${NGINX_HOST};
  listen ${NGINX_PORT};
    try_files $uri $uri/ /index.php?$args;

现在是空变量:

$ echo ${NGINX_HOST}

$ echo ${NGINX_PORT}

为这些变量设置默认值:

$ NGINX_HOST=${NGINX_HOST:-localhost}
$ NGINX_PORT=${NGINX_PORT:-80}
$ echo ${NGINX_HOST}
localhost
$ echo ${NGINX_PORT}
80

尝试使用 envsubst:

$ envsubst \
    '${NGINX_HOST} ${NGINX_PORT}' \
    < nginx-default.conf.template \
    | egrep 'server_name|listen|try_files' 
    
  server_name ;
  listen ;
  try_files $uri $uri/ /index.php?$args;

如您所见,它不起作用。必须对变量进行“导出”才能使其正常工作。这是第二次运行:

$ export NGINX_HOST=${NGINX_HOST:-localhost}
$ export NGINX_PORT=${NGINX_PORT:-80}

$ envsubst   '${NGINX_HOST} ${NGINX_PORT}' <  nginx-default.conf.template | egrep 'server_name|listen|try_files' 

  server_name localhost;
  listen 80;
    try_files $uri $uri/ /index.php?$args;

如您所见,现在它起作用了。希望它对其他人有帮助。

答案4

在调用之前,envsubst您应该使用单引号导出来恢复VAR_1修改。如:

export VAR_1='somevalue'

欲了解更多详情,请参阅:

如何替换复杂文本文件中的 shell 变量

相关内容