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

9

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

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

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

我不想仅仅使用printf的原因是Apache配置大约有20行,将占用大部分bash脚本,并且使其更难阅读。

感谢您的帮助。


将原型 httpd.conf 文件单独保存,并在脚本运行时将模板(原型)文件编辑为实际文件。当然,这意味着需要两个文件 - 脚本和模板。但它可以保持两个逻辑上不相关的文件实际上是不相关的。 - Jonathan Leffler
是的,那就是我想问的(如果不清楚,对不起),但我需要知道如何做到这一点。我认为Péter Varga的答案会帮助我实现这个目标,需要进行一些微调。 - Brendan
3个回答

12

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

编写一个类似下面的sed脚本(在sedawkperl等工具中):

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
请注意,你应该使用一个陷阱(trap)来确保临时变量不会超出其有用的生命周期:
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_status


5
我很惊讶没有人提到这里的文档。这可能不是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

在这种情况下,我建议使用 ${variable} 而不是等价的 $variable,以增强清晰度并避免任何可能的歧义。

2

使用类似于sed的命令,例如:

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

我该如何用不同的值替换多个标记?例如,%foo% 替换为 $foo,%bar% 替换为 $bar。 - Brendan
1
简单:sed "s/%foo%/$foo/g;s/%bar%/$bar/g" - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接