[编辑] 我更改了我的答案,那是几年前的事了。
我喜欢上面FooF的答案:
https://dev59.com/l2025IYBdhLWcg3wHR4Y#30872526
然而,我不想要一个中间变量将模板文件的整个内容存储在内存中。
. "${config_file}"
eval "echo \"$(cat "${template_file}")\""
示例
创建一个模板文件。我们把它叫做example.tpl
:
Hello, ${NAME}!
Today, the weather is ${WEATHER}. Enjoy!
创建一个配置文件来存储您的变量。我们将其称为
good.conf
:
NAME=John
WEATHER=good
现在,在你想要呈现模板的脚本中,你可以写入以下内容:
#!/usr/bin/env bash
template_file=example.tpl
config_file=good.conf
. "${config_file}"
eval "echo \"$(cat "${template_file}")\""
eval "echo \"$(cat "${template_file}")\"" > out
你应该能看到这个美妙的输出 :)
Hello, John!
Today, the weather is good. Enjoy!
谨慎使用eval
当您使用eval
时,如果模板文件包含某些指令,它们将被执行,这可能是危险的。例如,让我们将上面的example.tpl
更改为以下内容:
Hello, ${NAME}!
Today, the weather is ${WEATHER}. Enjoy!
I'm a hacker, hu hu! Look, fool!
$(ls /)
现在,如果您渲染模板文件,您将看到以下内容:
Hello, John!
Today, the weather is good. Enjoy!
I'm a hacker, hu hu! Look, fool!
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
现在请编辑您的文件
good.conf
,并将其内容改为以下内容:
NAME=$(ls -l /var)
WEATHER=good
并渲染模板。您应该看到类似于这样的内容:
Hello, total 8
drwxr-xr-x. 2 root root 6 Apr 11 04:59 adm
drwxr-xr-x. 5 root root 44 Sep 11 18:04 cache
drwxr-xr-x. 3 root root 34 Sep 11 18:04 db
drwxr-xr-x. 3 root root 18 Sep 11 18:04 empty
drwxr-xr-x. 2 root root 6 Apr 11 04:59 games
drwxr-xr-x. 2 root root 6 Apr 11 04:59 gopher
drwxr-xr-x. 3 root root 18 May 9 13:48 kerberos
drwxr-xr-x. 28 root root 4096 Oct 8 00:30 lib
drwxr-xr-x. 2 root root 6 Apr 11 04:59 local
lrwxrwxrwx. 1 root root 11 Sep 11 18:03 lock -> ../run/lock
drwxr-xr-x. 8 root root 4096 Oct 8 04:55 log
lrwxrwxrwx. 1 root root 10 Sep 11 18:03 mail -> spool/mail
drwxr-xr-x. 2 root root 6 Apr 11 04:59 nis
drwxr-xr-x. 2 root root 6 Apr 11 04:59 opt
drwxr-xr-x. 2 root root 6 Apr 11 04:59 preserve
lrwxrwxrwx. 1 root root 6 Sep 11 18:03 run -> ../run
drwxr-xr-x. 8 root root 87 Sep 11 18:04 spool
drwxrwxrwt. 4 root root 111 Oct 9 09:02 tmp
drwxr-xr-x. 2 root root 6 Apr 11 04:59 yp!
Today, the weather is good. Enjoy!
I'm a hacker, hu hu! Look, fool!
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
swapfile
sys
tmp
usr
var
如您所见,
配置文件和
模板文件中都存在命令注入的可能性,因此您需要格外小心:
- 确保模板文件的内容正确:检查是否存在命令注入。
- 确保配置文件的内容正确:同样检查是否存在命令注入。如果配置文件来自他人,则在渲染模板之前,您需要知道并信任该人。
想象一下,您是一个没有密码限制的sudo用户,渲染模板文件可能会用一条巧妙的rm -rf
命令毁坏您的系统。
只要您掌控这些文件的内容,使用eval
模板就可以了。
如果您有一个外部(不受信任的)配置文件,则应该寻找一个模板引擎,以隔离此类注入。例如,Jinja2模板在Python中非常出名。