Bash 模板:如何使用 Bash 从模板构建配置文件? [英] Bash Templating: How to build configuration files from templates with Bash?

查看:32
本文介绍了Bash 模板:如何使用 Bash 从模板构建配置文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本来为我自己的网络服务器自动创建 Apache 和 PHP 的配置文件.我不想使用 CPanel 或 ISPConfig 之类的任何 GUI.

I'm writing a script to automate creating configuration files for Apache and PHP for my own webserver. I don't want to use any GUIs like CPanel or ISPConfig.

我有一些 Apache 和 PHP 配置文件的模板.Bash 脚本需要读取模板,进行变量替换并将解析后的模板输出到某个文件夹中.最好的方法是什么?我可以想到几种方法.哪一个是最好的,或者可能有一些更好的方法来做到这一点?我想在纯 Bash 中做到这一点(例如在 PHP 中很容易)

I have some templates of Apache and PHP configuration files. Bash script needs to read templates, make variable substitution and output parsed templates into some folder. What is the best way to do that? I can think of several ways. Which one is the best or may be there are some better ways to do that? I want to do that in pure Bash (it's easy in PHP for example)

1) 如何替换文本文件中的 ${} 占位符?

模板.txt:

the number is ${i}
the word is ${word}

script.sh:

#!/bin/sh

#set variables
i=1
word="dog"
#read in template one line at the time, and replace variables
#(more natural (and efficient) way, thanks to Jonathan Leffler)
while read line
do
    eval echo "$line"
done < "./template.txt"

顺便说一句,我如何将输出重定向到这里的外部文件?如果变量包含引号,我需要转义吗?

BTW, how do I redirect output to external file here? Do I need to escape something if variables contain, say, quotes?

2) 使用 cat &sed 用其值替换每个变量:

2) Using cat & sed for replacing each variable with its value:

给定的 template.txt:

Given template.txt:

The number is ${i}
The word is ${word}

命令:

cat template.txt | sed -e "s/${i}/1/" | sed -e "s/${word}/dog/"

对我来说似乎很糟糕,因为需要转义许多不同的符号,并且有许多变量,该行会太长.

Seems bad to me because of the need to escape many different symbols and with many variables the line will be tooooo long.

你能想到其他优雅且安全的解决方案吗?

Can you think of some other elegant and safe solution?

推荐答案

你可以使用这个:

perl -p -i -e 's/${([^}]+)}/defined $ENV{$1} ? $ENV{$1} : $&/eg' < template.txt

用相应的环境变量替换所有 ${...} 字符串(在运行此脚本之前不要忘记导出它们).

to replace all ${...} strings with corresponding enviroment variables (do not forget to export them before running this script).

对于纯 bash 这应该可以工作(假设变量不包含 ${...} 字符串):

For pure bash this should work (assuming that variables do not contain ${...} strings):

#!/bin/bash
while read -r line ; do
    while [[ "$line" =~ (${[a-zA-Z_][a-zA-Z_0-9]*}) ]] ; do
        LHS=${BASH_REMATCH[1]}
        RHS="$(eval echo ""$LHS"")"
        line=${line//$LHS/$RHS}
    done
    echo "$line"
done

.如果 RHS 引用某些引用自身的变量,则不会挂起的解决方案:

. Solution that does not hang if RHS references some variable that references itself:

#!/bin/bash
line="$(cat; echo -n a)"
end_offset=${#line}
while [[ "${line:0:$end_offset}" =~ (.*)(${([a-zA-Z_][a-zA-Z_0-9]*)})(.*) ]] ; do
    PRE="${BASH_REMATCH[1]}"
    POST="${BASH_REMATCH[4]}${line:$end_offset:${#line}}"
    VARNAME="${BASH_REMATCH[3]}"
    eval 'VARVAL="$'$VARNAME'"'
    line="$PRE$VARVAL$POST"
    end_offset=${#PRE}
done
echo -n "${line:0:-1}"

警告:我不知道在 bash 中正确处理带有 NUL 的输入或保留尾随换行符数量的方法.最后一个变体按原样呈现是因为 shell 喜欢"二进制输入:

WARNING: I do not know a way to correctly handle input with NULs in bash or preserve the amount of trailing newlines. Last variant is presented as it is because shells "love" binary input:

  1. read 将解释反斜杠.
  2. read -r 不会解释反斜杠,但如果最后一行不以换行符结尾,仍会删除最后一行.
  3. "$(...)" 将删除尽可能多的尾随换行符,所以我用 结束 ...;echo -na 并使用 echo -n "${line:0:-1}":这会删除最后一个字符(即 a)并保留与输入中的尾随换行符一样多(包括 no).
  1. read will interpret backslashes.
  2. read -r will not interpret backslashes, but still will drop the last line if it does not end with a newline.
  3. "$(…)" will strip as many trailing newlines as there are present, so I end with ; echo -n a and use echo -n "${line:0:-1}": this drops the last character (which is a) and preserves as many trailing newlines as there was in the input (including no).

这篇关于Bash 模板:如何使用 Bash 从模板构建配置文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆