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

Tags:

Printf

Bash

Awk

Sed