khe*_*aud 46 bash configuration templates template-engine
我必须创建conf文件,init.d它们非常相似.这些文件允许在我的服务器上部署新的http服务.这些文件是相同的,只有一些参数从一个文件更改为另一个文件(listen_port域,服务器上的路径......).
由于这些文件中的任何错误都会导致服务错误,我想使用bash脚本创建这些文件.
例如:
generate_new_http_service.sh 8282 subdomain.domain.com /home/myapp/rootOfHTTPService
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种可以与bash一起使用的模板模块.这个模板模块将使用一些通用的conf和init.d脚本来创建新的脚本.
你有提示吗?如果不是,我可以使用python模板引擎.
dog*_*ane 77
你可以使用heredoc来做到这一点.例如
generate.sh:
#!/bin/sh
#define parameters which are passed in.
PORT=$1
DOMAIN=$2
#define the template.
cat << EOF
This is my template.
Port is $PORT
Domain is $DOMAIN
EOF
Run Code Online (Sandbox Code Playgroud)
输出:
$ generate.sh 8080 domain.com
This is my template.
Port is 8080
Domain is domain.com
Run Code Online (Sandbox Code Playgroud)
或将其保存到文件:
$ generate.sh 8080 domain.com > result
Run Code Online (Sandbox Code Playgroud)
小智 42
bash的模板模块?使用sed,卢克!以下是数百万种可能的方法之一的示例:
$ cat template.txt
#!/bin/sh
echo Hello, I am a server running from %DIR% and listening for connection at %HOST% on port %PORT% and my configuration file is %DIR%/server.conf
$ cat create.sh
#!/bin/sh
sed -e "s;%PORT%;$1;g" -e "s;%HOST%;$2;g" -e "s;%DIR%;$3;g" template.txt > script.sh
$ bash ./create.sh 1986 example.com /tmp
$ bash ./script.sh
Hello, I am a server running from /tmp and listening for connection at example.com on port 1986 and my configuration file is /tmp/server.conf
$
Run Code Online (Sandbox Code Playgroud)
Kim*_*bel 21
你可以直接在bash中这样做,你甚至不需要sed.写一个这样的脚本:
#!/bin/bash
cat <<END
this is a template
with $foo
and $bar
END
Run Code Online (Sandbox Code Playgroud)
然后像这样称呼它:
foo=FOO bar=BAR ./template
Run Code Online (Sandbox Code Playgroud)
Foo*_*ooF 11
对于简单的文件生成,基本上做
. "${config_file}"
template_str=$(cat "${template_file}")
eval "echo \"${template_str}\""
Run Code Online (Sandbox Code Playgroud)
就够了
这里${config_file}包含shell可解析格式的配置变量,并且${template_file}是看起来像shell here文档的模板文件.文件中的第一行源${config_file},第二行将文件的内容${template_file}放入shell变量中template_str.最后在第三行中我们构建了shell命令echo "${template_str}"("${template_str}"扩展了双引号表达式)并对其进行了评估.
有关这两个文件内容的示例,请参阅https://serverfault.com/a/699377/120756.
您可以在模板文件中拥有限制,或者需要执行shell转义.此外,如果模板文件是外部生成的,那么出于安全原因,您需要考虑在执行之前实施适当的过滤,这样当有人$(rm -rf /)在模板文件中注入着名文件时,您就不会丢失文件.
[编辑] 我从几年前的原始答案中更改了我的答案。
我喜欢上面 FooF 的答案:https ://stackoverflow.com/a/30872526/3538173
然而,我不希望有一个中间变量来将模板文件的全部内容存储在内存中。
. "${config_file}"
eval "echo \"$(cat "${template_file}")\""
Run Code Online (Sandbox Code Playgroud)
创建模板文件。让我们称之为example.tpl:
Hello, ${NAME}!
Today, the weather is ${WEATHER}. Enjoy!
Run Code Online (Sandbox Code Playgroud)
创建一个配置文件来存储您的变量。让我们称之为good.conf:
NAME=John
WEATHER=good
Run Code Online (Sandbox Code Playgroud)
现在,在要渲染模板的脚本中,您可以这样写:
#!/usr/bin/env bash
template_file=example.tpl
config_file=good.conf
. "${config_file}"
eval "echo \"$(cat "${template_file}")\""
# Or store the output in a file
eval "echo \"$(cat "${template_file}")\"" > out
Run Code Online (Sandbox Code Playgroud)
你应该看到这个美妙的输出:)
Hello, John!
Today, the weather is good. Enjoy!
Run Code Online (Sandbox Code Playgroud)
eval当您使用 时eval,如果模板文件包含一些指令,它们将被执行,并且可能是危险的。例如,让我们example.tpl用以下内容更改上面的内容:
Hello, ${NAME}!
Today, the weather is ${WEATHER}. Enjoy!
I'm a hacker, hu hu! Look, fool!
$(ls /)
Run Code Online (Sandbox Code Playgroud)
现在,如果您渲染模板文件,您将看到:
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
Run Code Online (Sandbox Code Playgroud)
现在编辑您的文件good.conf以包含以下内容:
NAME=$(ls -l /var)
WEATHER=good
Run Code Online (Sandbox Code Playgroud)
并渲染模板。您应该会看到如下内容:
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
Run Code Online (Sandbox Code Playgroud)
如您所见,配置文件和模板文件中的命令注入是可能的,这就是您必须格外小心的原因:
想象一下,你是一个没有密码的 sudoer,渲染模板文件可能会导致你的系统被一个放置良好的rm -rf.
只要您控制这些文件的内容,就可以使用此eval模板。
如果您有一个外部(不受信任的)传入配置文件,您应该寻找模板引擎,它将隔离这些类型的注入。例如,Jinja2 模板在 Python 中非常有名。
小智 5
这是我最终解决这个问题的方法.我发现它比上面的一些方法更灵活,它避免了一些引号问题.
fill.sh:
#!/usr/bin/env sh
config="$1"
template="$2"
destination="$3"
cp "$template" "$destination"
while read line; do
setting="$( echo "$line" | cut -d '=' -f 1 )"
value="$( echo "$line" | cut -d '=' -f 2- )"
sed -i -e "s;%${setting}%;${value};g" "$destination"
done < "$config"
Run Code Online (Sandbox Code Playgroud)
模板:
Template full of important %THINGS%
"Note that quoted %FIELDS% are handled correctly"
If I need %NEWLINES% then I can add them as well.
Run Code Online (Sandbox Code Playgroud)
配置:
THINGS=stuff
FIELDS="values work too!"
NEWLINES="those\\nnifty\\nlinebreaks"
Run Code Online (Sandbox Code Playgroud)
结果: 模板充满了重要的东西
"Note that quoted "values work too!" are handled correctly"
If I need those
nifty
linebreaks then I can add them as well.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50969 次 |
| 最近记录: |