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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8841195/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:17:41  来源:igfitidea点击:

How can I script file generation from a template using bash?

bashsedawkprintf

提问by Brendan

I am trying to automate the set up of site creation for our in-house development server.

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

Currently, this consists of creating a system user, mysql user, database, and apache config. I know how I can do everything in a single bash file, but I wanted to ask if there was a way to more cleanly generate the apache config.

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

Essentially what I want to do is generate a conf file based on a template, similar to using printf. I could certainly use printf, but I thought there might be a cleaner way, using sed or awk.

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

The reason I don't just want to use printf is because the apache config is about 20 lines long, and will take up most of the bash script, as well as make it harder to read.

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

Any help is appreciated.

任何帮助表示赞赏。

回答by Jonathan Leffler

Choose a way of marking parameters. One possibility is :parameter:, but any similar pair of markers that won't be confused with legitimate text for the template file(s) is good.

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

Write a sedscript (in sed, awk, perl, ...) similar to the following:

编写类似于以下内容的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

If you get to a point where you need sometimes to edit something and sometimes don't, you may find it easier to create the relevant sedcommands in a command file and then execute that:

如果您有时需要编辑某些内容有时不需要,您可能会发现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

Note that you should use a trap to ensure the temporary doesn't outlive its usefulness:

请注意,您应该使用陷阱来确保临时文件不会超过其有用性:

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

This ensures that your temporary file is removed when the script exits for most plausible signals. You can preserve a non-zero exit status from previous commands and use exit $exit_statusafter the trap 0command.

这可确保在脚本退出以获取大多数可能的信号时删除您的临时文件。您可以保留先前命令的非零退出状态并exit $exit_statustrap 0命令之后使用。

回答by tripleee

I'm surprised nobody mentioned here documents. This is probably not what the OP wants, but certainly a way to improve legibility of the script you started out with. Just take care to escape or parametrize away any constructs which the shell will perform substitutions on.

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

#!/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

In this context I would recommend ${variable} over the equivalent $variable for clarity and to avoid any possible ambiguity.

在这种情况下,为了清晰起见并避免任何可能的歧义,我会推荐 ${variable} 而不是等效的 $variable。

回答by ???

Use sed like for example

例如使用 sed

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