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
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)
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
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
.
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.
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
"
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;
}
}