Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

what I want to acomplish is:

1.) Having a config file as template, with variables like $version $path (for example apache config)

2.) Having a shell script that "fills in" the variables of the template and writes the generated file to disk.

Is this possible with a shell script. I would be very thankfull if you can name some commands/tools I can accomplish this or some good links.

share|improve this question
add comment

4 Answers

up vote 10 down vote accepted

This is very possible. A very simple way to implement this would be for the template file to actually be the script and use shell variables such as

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
cat > /tmp/destfile <<-EOF
here is some config for version $version which should
also reference this path $path
EOF

You could even make this configurable on the command line by specifying version=$1 and path=$2, so you can run it like bash script /foo/bar/baz 1.2.3. The - before EOF causes whitespace before the lines be ignored, use plain <<EOF if you do not want that behavior.

Another way to do this would be to use the search and replace functionality of sed

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
sed -e "s/VERSION/$version/g" -e "s/PATH/$path/" /path/to/templatefile > /tmp/destfile

which would replace each instance of the strings VERSION and PATH. If there are other reasons those strings would be in the template file you might make your search and replace be VERSION or %VERSION% or something less likely to be triggered accidentally.

share|improve this answer
add comment

You probably ought to look into a configuration management system like Puppet or Chef. These can easily do what you describe above and much more.

share|improve this answer
    
thanks. Absolutely, I have Chef installed and running. But it adds a lot of overhead, when you have to write your own cookbooks. I do not know the ruby programming language and my conclusion was. its easier to do this with a shell script for the easier cases (if possible). –  Markus Jul 6 '11 at 21:42
    
Looks like Puppet and Chef both use ERB for templates, and that's ridiculously easy to get started with. Given a variable name, the string <%= name %> in a template will get replaced with name's value. How you define name outside the template differs between the two systems, obviously. –  Mike Renfro Jul 6 '11 at 23:42
    
Yes templating (With Chef) itself is absolutely easy. But using chef as Framework (and writing the cookbooks) requires a lot of time. To get the data into the templates you need to understand where and how Chef manages the "merging" of datasources and a lot of other stuff. I have started writing my own cookbooks, but a shell script would in my special case be 100 times faster... –  Markus Jul 15 '11 at 18:49
add comment

If you want lightweight and real templates rather than shell code that generates new files, the usual choices are sed& awk or perl. Here is one link: http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/

Me, I'd use a real language like perl, tcl, python, ruby or something else in that class. Something built for scripting. They all have good, simple templating tools and tons of examples in google.

share|improve this answer
add comment

I use shtpl for that. (private project of mine, which means, it is not widely in use. But maybe you want to test it anyway)

For example you want to generate an /etc/network/interfaces out of a csv-file, you can do it like that:

CSV-file content (here test.csv):

eth0;10.1.0.10;255.255.0.0;10.1.0.1
eth1;192.168.0.10; 255.255.255.0;192.168.0.1

Template (here interfaces.tpl):

#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1 
iface $Val1 inet static
  address $Val2 
  netmask $Val3 
  gateway $Val4 

#% done < "$CSVFILE"

Command:

$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"

Result:

auto eth0 
iface eth0 inet static
  address 10.1.0.10 
  netmask 255.255.0.0 
  gateway 10.1.0.1 

auto eth1 
iface eth1 inet static
  address 192.168.0.10 
  netmask  255.255.255.0 
  gateway 192.168.0.1

Enjoy!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.