将文件中的环境变量替换为其实际值?

将文件中的环境变量替换为其实际值?

有没有一种简单的方法来替换/评估文件中的环境变量?

假设我有一个文件,config.xml其中包含:

<property>
    <name>instanceId</name>
    <value>$INSTANCE_ID</value>
</property>
<property>
    <name>rootPath</name>
    <value>/services/$SERVICE_NAME</value>
</property>

...ETC。

我想用环境变量$INSTANCE_ID的值替换文件中的env var的值。INSTANCE_ID$SERVICE_NAMESERVICE_NAME

我不会先验地知道需要哪些环境变量(或者更确切地说,如果有人向配置文件添加新的环境变量,我不想更新脚本)。

答案1

你可以使用envsubst(部分gnu gettext):

envsubst < infile

将用相应的值替换文件中的环境变量。变量名称必须仅由字母数字或下划线 ASCII 字符组成,不能以数字开头且不能为空;否则这样的变量引用将被忽略。

gettext envsubst该支持${VAR:-default}和额外功能的一些替代方案:
rust选择
go选择
node.js选择


仅替换某些环境变量,看到这个问题。

答案2

这不是很好,但是很有效

( echo "cat <<EOF" ; cat config.xml ; echo EOF ) | sh

如果它是在 shell 脚本中,它看起来像:

#! /bin/sh
cat <<EOF
<property>
    <name>instanceId</name>
    <value>$INSTANCE_ID</value>
</property>
EOF

编辑,第二个提案:

eval "echo \"$(cat config.xml)\""

编辑,与问题不严格相关,但如果从文件中读取变量:

(. .env && eval "echo \"$(cat config.xml)\"")

答案3

如果您碰巧有 Perl(但没有 gettext 和envsubst),您可以使用简短的脚本进行简单的替换:

$ export INSTANCE_ID=foo; export SERVICE_NAME=bar;
$ perl -pe 's/\$([_A-Z]+)/$ENV{$1}/g'  < config.xml
<property>
    <name>instanceId</name>
    <value>foo</value>
</property>
<property>
    <name>rootPath</name>
    <value>/services/bar</value>
</property>

我假设变量名称只有大写字母和下划线,但第一个模式应该很容易根据需要进行更改。 $ENV{...}引用 Perl 看到的环境。

如果您想支持${...}语法或在未设置的变量上抛出错误,您将需要更多的工作。与gettext'的近似等价物envsubst是:

perl -pe 's/\$(\{)?([a-zA-Z_]\w*)(?(1)\})/$ENV{$2}/g'

尽管我觉得通过进程环境提供这样的变量一般来说似乎有点不确定:您不能在文件中使用任意变量(因为它们可能具有特殊含义),并且某些值可能至少具有半-其中的敏感数据。

答案4

继续 Perl 和 PHP 示例,下面是一个 Python oneliner:

python -c 'import os,sys; sys.stdout.write(os.path.expandvars(sys.stdin.read()))' < in.file > out.file

不幸的是,并不是每个环境都已envsubst安装。

相关内容