Linux Envsubst Command

使用 envsubst 命令替换环境变量

在写脚本或者运行脚本的时候,很多时候都会用到环境变量,不过有时候使用的变量可能会带来安全风险。所以这时候我们可以使用 envsubst 来代替环境变量。

envsubst 命令用于获取环境变量的替代项(可能这就是这个命令名称的由来:environment substitute)。

但是它不会直接改变环境变量,首先会根据模式查找变量(比如 $VARIABLE 或者 [$VARIABLE]);然后,它会用一个 bash 变量替换找到的环境变量。

注意:envsubst 命令只识别导出的变量(exported variables)。

使用 envsubst 命令替换环境变量,可参考如下语法模式:


envsubst [OPTION] [SHELL-FORMAT]

接下来我们来看看具体怎么做。
首先我们准备一个文本文件,比如将其命名为 confidential.txt,内容如下:


A sample file containg password and username!

And should not be shared by any means.

My loging credentials are:

        username=$USERNAME
        password=$PASSWORD

然后,为了替换 $USERNAME 和 $PASSWORD,我们首先创建并导出两个变量:


export USERNAME=abhiman
export PASSWORD=strongphrase

导出变量值后,可以为创建的文件调用 envsubst 命令:


envsubst < confidential.txt

如下所示,变量的值已经被改变了。


vxbus@vxworks:~/github$ export USERNAME=abhiman
vxbus@vxworks:~/github$ export PASSWORD=strongphrase
vxbus@vxworks:~/github$ envsubst < confidential.txt 
A sample file containg password and username!

And should not be shared by any means.

My loging credentials are:

        username=abhiman
        password=strongphrase

另外,还可以使用 unset 命令取消变量值的设置。首先,unset 使用 export 命令设置的变量:


unset USERNAME PASSWORD

现在,再次运行 envsubst 命令,可看到变量的值已经没有了:


vxbus@vxworks:~/github$ unset USERNAME PASSWORD
vxbus@vxworks:~/github$ envsubst < confidential.txt 
A sample file containg password and username!

And should not be shared by any means.

My loging credentials are:

        username=
        password=
mark@vxworks:~/github$ 

因为 envsubst 命令只适用于导出的变量,当我们使用 unset 命令的时候,将变量的值设置为了 null。然后当 envsubst 命令找不到要替换的值的时候,就会出现空内容。

将输出重定向到特定文件

我们可以选择将输出重定向到某个文件,以保存输出内容,可使用重定向符号 > 来实现。比如,我们将上述输出重定向到 Output.txt:


envsubst < confidential.txt > Output.txt

运行效果如下:


vxbus@vxworks:~/github$ export USERNAME=abhiman
vxbus@vxworks:~/github$ export PASSWORD=strongphrase
vxbus@vxworks:~/github$ envsubst < confidential.txt > Output.txt
vxbus@vxworks:~/github$ cat Output.txt 
A sample file containg password and username!

And should not be shared by any means.

My loging credentials are:

        username=abhiman
        password=strongphrase
vxbus@vxworks:~/github$ 

以 shell 的方式替换 envsubst 命令中的特定变量

假如你导出了多个环境变量,但是只想替换其中的一小部分。这种情况下,可以使用 shell 的方式来实现。其语法非常灵活,只需要在单引号 '' 中指定变量即可,可通过多种方式使用它,比如:


envsubst '$variable' > file

或者添加多个变量:


envsubst '$variable1 $variable1 $variable3' > file

也可以添加文本:


envsubst 'subsitute the $variable1 and $variable2' > file

下面这个例子,我们使用一个名为 Substitute.txt 的文本文件,其内容如下:


Hello, My name is $USER.

And these are login credentials for $SERVICE:

        username=$USERNAME
        password=$PASSWORD

Not meant for public use!

接下来,我将导出上面文件中使用的每个变量的值:


export USER=sagar export SERVICE=AWS export USERNAME=LHB export PASSWORD=randomphrase  

在不替换任何特定变量的情况下,它应该会得到以下输出:


vxbus@vxworks:~/github$ export USER=sagar export SERVICE=AWS export USERNAME=LHB export PASSWORD=randomphrase  
vxbus@vxworks:~/github$ envsubst < Substitute.txt 
Hello, My name is sagar.

And these are login credentials for AWS:

        username=LHB
        password=randomphrase

Not meant for public use!
vxbus@vxworks:~/github$ 

如果我只希望 $USER 和 $SERVICE 的值反映在输出中,可使用如下命令:


envsubst '$USER $SERVICE' < Substitute.txt

vxbus@vxworks:~/github$ export USER=sagar export SERVICE=AWS export USERNAME=LHB export PASSWORD=randomphrase  
vxbus@vxworks:~/github$ envsubst '$USER $SERVICE' < Substitube.txt 
Hello, My name is sagar.

And these are login credentials for AWS:

        username=$USERNAME
        password=$PASSWORD

Not meant for public use!
vxbus@vxworks:~/github$ 

如上所示,输出只显示了 $USER 和 $SERVICE 的值,但是 $USERNAME 和 $PASSWORD 仍旧保持原值。