如何使用bash从模板生成脚本文件?

如何使用bash从模板生成脚本文件?,bash,sed,awk,printf,Bash,Sed,Awk,Printf,我正在尝试为我们的内部开发服务器自动设置站点创建 目前,这包括创建系统用户、mysql用户、数据库和apache配置。我知道如何在一个bash文件中完成所有工作,但我想问问是否有更干净地生成apache配置的方法 基本上,我想做的是基于模板生成一个conf文件,类似于使用printf。我当然可以使用printf,但我认为可能有更干净的方法,使用sed或awk 我之所以不想使用printf,是因为apache配置大约有20行长,将占用bash脚本的大部分,并且使其更难阅读 任何帮助都将不胜感激。例

我正在尝试为我们的内部开发服务器自动设置站点创建

目前,这包括创建系统用户、mysql用户、数据库和apache配置。我知道如何在一个bash文件中完成所有工作,但我想问问是否有更干净地生成apache配置的方法

基本上,我想做的是基于模板生成一个conf文件,类似于使用printf。我当然可以使用printf,但我认为可能有更干净的方法,使用sed或awk

我之所以不想使用printf,是因为apache配置大约有20行长,将占用bash脚本的大部分,并且使其更难阅读


任何帮助都将不胜感激。

例如,使用sed like

sed s/%foo%/$foo/g template.conf > $newdir/httpd.conf

选择标记参数的方式。一种可能是
:参数:
,但任何不会与模板文件的合法文本混淆的类似标记对都是好的

编写一个
sed
脚本(在
sed
awk
perl
,…)如下所示:

sed -e "s/:param1:/$param1/g" \
    -e "s/:param2:/$param2/g" \
    -e "s/:param3:/$param3/g" \
    httpd.conf.template > $HTTPDHOME/etc/httpd.conf
如果您有时需要编辑某些内容,有时不需要,您可能会发现在命令文件中创建相关的
sed
命令,然后执行该命令更容易:

{
echo "s/:param1:/$param1/g"
echo "s/:param2:/$param2/g"
echo "s/:param3:/$param3/g"
if [ "$somevariable" = "somevalue" ]
then echo "s/normaldefault/somethingspecial/g"
fi
} >/tmp/sed.$$
sed -f /tmp/sed.$$ httpd.conf.template > $HTTPDHOME/etc/httpd.conf
请注意,您应该使用陷阱来确保临时文件不会过期:

tmp=/tmp/sed.$$   # Consider using more secure alternative schemes
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15  # aka EXIT HUP INT QUIT PIPE TERM
...code above...
rm -f $tmp
trap 0

这可以确保在脚本退出时删除临时文件以获取最合理的信号。您可以保留以前命令的非零退出状态,并在
trap 0
命令之后使用
exit$exit\u status

我很惊讶这里没有人提到文档。这可能不是OP想要的,但肯定是一种提高脚本可读性的方法。只要注意转义或参数化掉shell将对其执行替换的任何构造

#!/bin/sh
# For example's sake, a weird value
# This is in single quotes, to prevent substitution
literal='$%"?*=`!!'
user=me

cat <<HERE >httpd.conf
# Not a valid httpd.conf
User=${user}
Uninterpolated=${literal}
Escaped=\$dollar
HERE
#/垃圾箱/垃圾箱
#例如,看在上帝的份上,一个奇怪的值
#这是单引号,以防止替换
文字=“$%”?*=“!!”
用户=我

cat将原型httpd.conf文件分开保存,并让脚本在运行时将模板(原型)文件编辑为实际文件。当然,这意味着需要两个文件——脚本和模板。但它将两个逻辑上不相交的文件实际上不相交。是的,这就是我要问的(如果不清楚,请抱歉)但我需要知道如何做到这一点。我认为Péter Varga的答案将通过一些调整让我达到目的。我将如何用多个不同的值替换多个标记?即%foo%替换为$foo,%bar%替换为$bar。简单:
sed“s/%foo%/$foo/g;s/%bar%/$bar/g“