Replace bash variables in template file

前端 未结 1 1416
独厮守ぢ
独厮守ぢ 2021-01-19 07:10

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. S

相关标签:
1条回答
  • 2021-01-19 07:42

    Security tips

    This don't take care of security issues! Using eval is evil!

    The compatible answer is not better!

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

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

    Quick way bash only!:

    Under bash you can simply:

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

    or

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

    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)\""
    

    Then

    echo "$cfgBody"
    

    and/or

    echo "$cfgBody" >/cfgpath/cfgfile
    

    Doing this into a loop

    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
    "
    

    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.

    Soft way (compatible answer)

    Under posix shell, you may do this way:

    #!/bin/sh
    
    (
        cat <<eohead
        #!/bin/sh
        INSTALLPATH='/somepath/somewhere'
        SITEURL='example.com'
        PHPSERV='127.0.0.1:9000';
        cat <<eof
    eohead
        cat template
        echo eof
    ) | /bin/sh
    

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

    bash Without eval !

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

    Could work into a loop:

    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
    "
    

    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
    

    Comparing outputs:

    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;
         }
    
     }
    
    0 讨论(0)
提交回复
热议问题