为了账号安全,请及时绑定邮箱和手机立即绑定

Bash模板:如何使用Bash从模板构建配置文件?

/ 猿问

Bash模板:如何使用Bash从模板构建配置文件?

一只名叫tom的猫 2019-11-23 11:15:40

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


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


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


template.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"

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


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


给定template.txt:


The number is ${i}

The word is ${word}

命令:


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

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


您能想到其他一些优雅安全的解决方案吗?


查看完整描述

3 回答

?
千万里不及你

您可以使用此:


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

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


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


#!/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引用一些引用自身的变量,则该解决方案不会挂起:


#!/ bin / bash

line =“ $(cat; echo -na)”

end_offset = $ {#line}

而[[“ $ {line:0:$ end_offset}” =〜(。*)(\ $ \ {([a-zA-Z _] [a-zA-Z_0-9] *)\})(。* )]];做

    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}

完成

echo -n“ $ {line:0:-1}”

警告:我不知道一种正确处理bash中NUL的输入或保留尾随换行符数量的方法。出现最后一个变体是因为壳“喜欢”二进制输入:


read 将解释反斜杠。

read -r 不会解释反斜杠,但如果不以换行符结尾,仍会删除最后一行。

"$(…)"因为有本将去除尽可能多的尾随换行符,所以我最终…与; echo -n a和使用echo -n "${line:0:-1}":此下降的最后一个字符(这是a)和蜜饯尽可能多的尾随换行符有一个在输入(包括无)。


查看完整回答
反对 回复 2019-11-23
?
慕沐林林

尝试 envsubst


FOO=foo

BAR=bar

export FOO BAR


envsubst <<EOF

FOO is $FOO

BAR is $BAR

EOF


查看完整回答
反对 回复 2019-11-23
?
qq_笑_17

envsubst对我来说是新的。太棒了


记录下来,使用Heredoc是配置conf文件的好方法。


STATUS_URI="/hows-it-goin";  MONITOR_IP="10.10.2.15";


cat >/etc/apache2/conf.d/mod_status.conf <<EOF

<Location ${STATUS_URI}>

    SetHandler server-status

    Order deny,allow

    Deny from all

    Allow from ${MONITOR_IP}

</Location>

EOF


查看完整回答
反对 回复 2019-11-23
  • 3 回答
  • 0 关注
  • 236 浏览
我要回答
慕课专栏
更多

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信