How can I script file generation from a template using bash?
Choose a way of marking parameters. One possibility is :parameter:
, but any similar pair of markers that won't be confused with legitimate text for the template file(s) is good.
Write a sed
script (in sed
, awk
, perl
, ...) similar to the following:
sed -e "s/:param1:/$param1/g" \
-e "s/:param2:/$param2/g" \
-e "s/:param3:/$param3/g" \
httpd.conf.template > $HTTPDHOME/etc/httpd.conf
If you get to a point where you need sometimes to edit something and sometimes don't, you may find it easier to create the relevant sed
commands in a command file and then execute that:
{
echo "s/:param1:/$param1/g"
echo "s/:param2:/$param2/g"
echo "s/:param3:/$param3/g"
if [ "$somevariable" = "somevalue" ]
then echo "s/normaldefault/somethingspecial/g"
fi
} >/tmp/sed.$$
sed -f /tmp/sed.$$ httpd.conf.template > $HTTPDHOME/etc/httpd.conf
Note that you should use a trap to ensure the temporary doesn't outlive its usefulness:
tmp=/tmp/sed.$$ # Consider using more secure alternative schemes
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15 # aka EXIT HUP INT QUIT PIPE TERM
...code above...
rm -f $tmp
trap 0
This ensures that your temporary file is removed when the script exits for most plausible signals. You can preserve a non-zero exit status from previous commands and use exit $exit_status
after the trap 0
command.
I'm surprised nobody mentioned here documents. This is probably not what the OP wants, but certainly a way to improve legibility of the script you started out with. Just take care to escape or parametrize away any constructs which the shell will perform substitutions on.
#!/bin/sh
# For example's sake, a weird value
# This is in single quotes, to prevent substitution
literal='$%"?*=`!!'
user=me
cat <<HERE >httpd.conf
# Not a valid httpd.conf
User=${user}
Uninterpolated=${literal}
Escaped=\$dollar
HERE
In this context I would recommend ${variable} over the equivalent $variable for clarity and to avoid any possible ambiguity.
Use sed like for example
sed s/%foo%/$foo/g template.conf > $newdir/httpd.conf