用bash脚本从模板创build新文件

我必须创build非常相似的conf文件和init.d 这些文件允许在我的服务器上部署新的http服务。 这些文件是相同的,只有一些参数从一个文件更改到另一个( listen_port ,域,服务器上的path…)。

由于这些文件中的任何错误导致服务错误,我想用bash脚本创build这些文件。

例如:

 generate_new_http_service.sh 8282 subdomain.domain.com /home/myapp/rootOfHTTPService 

我正在寻找一种模板,我可以使用bash。 这个模板模块将使用一些通用的conf和init.d脚本来创build新的模板。

你有提示吗? 如果没有,我可以使用Python模板引擎。

你可以用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 

输出:

 $ generate.sh 8080 domain.com This is my template. Port is 8080 Domain is domain.com 

或者将其保存到文件中:

 $ generate.sh 8080 domain.com > result 

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 $ 

你可以直接在bash中做这个,你甚至不需要sed。 写一个这样的脚本:

 #!/bin/bash cat <<END this is a template with $foo and $bar END 

然后像这样调用它:

 foo=FOO bar=BAR ./template 

对于简单的文件生成,基本上是做

  . "${config_file}" template_str=$(cat "${template_file}") eval "echo \"${template_str}\"" 

就足够了。

这里${config_file}包含shell可parsing格式的configurationvariables,而${template_file}是类似于shell here文档的模板文件。 第一行来源于文件${config_file} ,第二行将文件${template_file}放入shellvariablestemplate_str 。 最后在第三行中,我们构buildshell命令echo "${template_str}" (其中双引号expression式"${template_str}"被展开)并对其进行评估。

有关这两个文件的内容的示例,请参阅https://serverfault.com/a/699377/120756

你可以在模板文件中有什么限制,或者你需要执行shell转义。 此外,如果模板文件是外部生成的,那么出于安全原因,您需要考虑在执行之前实施适当的过滤,以便在有人在模板文件中注入着名的$(rm -rf /)时不会丢失文件。

你可以使用python类的string.Template

 $ echo 'before $X after' > template.txt $ python -c 'import string; print(string.Template(open("template.txt").read()).substitute({"X":"A"}))' before A after 

要么

 $ python -c 'import string, sys; print(string.Template(open("template.txt").read()).substitute({"X":sys.argv[1]}))' "A" 

这里$X是模板中的占位符, {"X":"A"}是占位符到值的映射。 在python代码中,我们从文件中读取模板文本,从中创build一个模板,然后用命令行参数replace占位符。

或者,如果您的计算机上安装了Ruby,则可以使用Ruby的ERB。

 $ echo "before <%= ENV['X'] %> after" > template.txt $ X=A erb template.txt before A after 

这里<%= ENV['X'] %>是一个占位符。 ENV['X']从环境variables中读取值。 X=A将环境variables设置为所需的值。

以下是我为自己做的事情:

 . "${config_file}" eval "cat << EOF $(cat ${template_file}) EOF" 

如果你想把它放在一个configuration文件中:

 . "${config_file}" eval "cat > /etc/MY_SERVICE/MY_CONFIG << EOF $(cat ${template_file}) EOF" 

这样,你不必创build额外的variables。