替换模板文件中的bash变量 [英] Replace bash variables in template file

查看:100
本文介绍了替换模板文件中的bash变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Bash来运行某种形式的安装过程.在此过程中,将复制配置文件,并在其中替换某些值.这样的配置可以在下面找到:

I am attempting to use Bash in order to run a form of an install process. During this process, a configuration file is copied and certain values are replaced inside of it. Such a config can be found below:

server {
    listen 80;
    root ${INSTALLPATH};
    server_name ${SITEURL};

    client_max_body_size 20m;
    client_body_timeout 120s;

    location / {
        try_files /public/router.php =404;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_pass ${PHPSERV};
        fastcgi_index router.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
    }

    location /assets {
        try_files /app/$uri =404;
    }

}

#Enables HTTPS access
#This requires you to install certificates and is not enabled by default
#If you wish to enable HTTPS, uncomment (remove the #s) from the below lines
#And change the ssl_certificate and ssl_certificate_key to point to the     correct
#certificates.

#server {
#    listen 443;
#    root ${INSTALLPATH};
#    server_name ${SITEURL};
#
#    ssl on;
#    ssl_certificate     /etc/nginx/ssl/site.crt;
#    ssl_certificate_key /etc/nginx/ssl/site.key;
#
#    location / {
#        try_files /public/router.php =404;
#        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
#        fastcgi_pass ${PHPSERV};
#        fastcgi_index router.php;
#        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#        include /etc/nginx/fastcgi_params;
#    }
#
#    location /assets {
#        try_files /app/$uri =404;
#    }
#
#}

我发现大多数示例都源自eval的使用,并且我尝试使用eval进行此替换,但是似乎这里的文件没有正确扩展,bash尝试执行一些操作并且可以t.

I have been finding that most examples stem off the use of eval, and I have tried using that to do this replacement, however it appears that the file here does not properly expand, and bash tries to execute some stuff and can't.

目前,我有这个

INSTALLPATH="/var/www/html/mycustomsite/"
PHPSERV="127.0.0.1:9000"
SITEURL="example.com"

while read -r line; do
    eval echo -e "${line}"
done < template

但是,这不能正确替换声明的值,也不能正确生成文件.例如,它会丢失以#开头的任何行并尝试执行其他行(以及丢失一些空格).

However, this does not properly replace the values that are declared, nor does it generate the file correctly. It loses for example any line that starts with # and tries to execute others (along with losing some spacing).

仅使用大多数Linux系统上可用的Bash和命令来执行此操作的正确方法是什么?

What would be the correct way to do this, using just Bash and commands available on most Linux systems?

推荐答案

安全提示

这不会解决安全问题!使用eval邪恶

兼容的答案并不更好!

当然,您必须对模板的内容充满信心!

Of course, you have to be confident about the content of your template!!

否则,请尝试使用的问题! (请参阅我的最后答案)

If else, try using sed! (see my last answer)

的问题,您可以简单地:

Under bash you can simply:

eval "INSTALLPATH='/somepath/somewhere' SITEURL='example.com' PHPSERV='127.0.0.1:9000'; echo \"$(<template)\""

eval "INSTALLPATH='/somepath/somewhere'
    SITEURL='example.com'
    PHPSERV='127.0.0.1:9000';
    echo \"$(<template)\""

使用eval时,可以将生成的配置文件存储到一个变量中:

As you're using eval, you could store your resulting config file into one variable:

eval "INSTALLPATH='/somepath/somewhere'
    SITEURL='example.com'
    PHPSERV='127.0.0.1:9000';
    cfgBody=\"$(<template)\""

然后

echo "$cfgBody"

和/或

echo "$cfgBody" >/cfgpath/cfgfile

将其循环执行

tmplBody="$(<template)"
while read INSTALLPATH SITEURL PHPSERV CFGFILE;do
    [ "$CFGFILE" ] && eval "echo \"$tmplBody\"" >"$CFGFILE"
  done <<<"
    /somepath/somewhere            example.com  127.0.0.1:9000  /tmp/file1
    '/some\ other\ path/elsewhere' sample2.com  127.0.0.1:9001  /tmp/file2
"

注意:在第二行上,有转义的空格(以反斜杠\ 引号'开头. strong>反斜杠告诉read不要拆分变量,并且必须将引号添加到结果/tmp/file2中.

Note: On second line, there are escaped spaces (prepanded with a backshash \ and quotes '. The backslash tell read to not split the variable, and the quotes have to be added into the resulting /tmp/file2.

的问题.

This don't require bash, was tested under dash and busybox.

sedcmd=''
for var in INSTALLPATH SITEURL PHPSERV;do
    printf -v sc 's/${%s}/%s/;' $var "${!var//\//\\/}"
    sedcmd+="$sc"
  done
sed -e "$sedcmd" <template

可能会陷入循环:

while read INSTALLPATH SITEURL PHPSERV CFGFILE;do
    if  [ "$CFGFILE" ] ;then
        sedcmd=''
        for var in INSTALLPATH SITEURL PHPSERV;do
            printf -v sc 's/${%s}/%s/;' $var "${!var//\//\\/}"
            sedcmd+="$sc"
          done
        sed -e "$sedcmd" <template >"$CFGFILE"
      fi
  done <<<"
    /somepath/somewhere             example.com  127.0.0.1:9000  /tmp/file1
    '/some\ other\ path/elsewhere'  sample2.com  127.0.0.1:9001  /tmp/file2
"

兼容的答案,使用sed

这可以在没有所谓的 bashisms 进入循环的情况下起作用:

Compatible answer, using sed

This could work without so called bashisms, into a loop:

#!/bin/sh

while read INSTALLPATH SITEURL PHPSERV CFGFILE;do

    sedcmd="s|\\\${INSTALLPATH}|${INSTALLPATH}|;"
    sedcmd="${sedcmd}s|\\\${SITEURL}|${SITEURL}|;"
    sedcmd="${sedcmd}s|\\\${PHPSERV}|${PHPSERV}|;"

    sed -e "$sedcmd" template >"$CFGFILE"

  done <<eof
    /somepath/somewhere             example.com  127.0.0.1:9000  /tmp/file1
    '/some\ other\ path/elsewhere'  sample2.com  127.0.0.1:9001  /tmp/file2
eof

比较输出:

diff -u99 /tmp/file{1,2}
--- /tmp/file1        2015-05-31 11:02:03.407463963 +0200
+++ /tmp/file2        2015-05-31 11:02:03.407463963 +0200
@@ -1,22 +1,22 @@
 server {
     listen 80;
-    root /somepath/somewhere;
-    server_name example.com;
+    root '/some other path/elsewhere';
+    server_name sample2.com;

     client_max_body_size 20m;
     client_body_timeout 120s;

     location / {
         try_files /public/router.php =404;
         fastcgi_split_path_info ^(.+?\.php)(/.*)$;
-        fastcgi_pass 127.0.0.1:9000;
+        fastcgi_pass 127.0.0.1:9001;
         fastcgi_index router.php;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include /etc/nginx/fastcgi_params;
     }

     location /assets {
         try_files /app/$uri =404;
     }

 }

这篇关于替换模板文件中的bash变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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