用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。