Monday, December 03, 2007

Templating Your Shell Script

My colleague wanted to run a set of predefined commands on a set of remote servers via SSH connection. However, the arguments used in the commands are very much server specific. In this type of situation, you may want to create a template shell so that your main script can convert the template to specific script commands.

My preference is to quote those variables using "@" sign. You can use any character that has special meaning in shell programming. Suppose you want to run this command in the target host:
cd some-dir; tar cvf /backup/host11-20071203.tar ./https-host11; gzip /backup/host11-20071203.tar
for host11 server.

What you can do is to quote it in the template like this:
cd some-dir; tar cvf /backup/@HOST@-@TAG@.tar ./https-@HOST@; gzip /backup/@HOST@-@TAG@.tar

By running "sed" (Stream Editor), you can do global substitution on the fly and even pipe it over to the ssh connection to get the things done automatically, just like this:

TAG="20071203"
for HOST in host2 host3 host5 host7 host11 host13 host17 host19
do
  sed -e "s/@HOST@/$HOST/g" -e "s/@TAG@/$TAG/g" command-template | ssh user@$HOST
done

You can ever dynamically define the date if your @TAG@ is supposed to represent the current date. This approach can help you to run template shell commands over a bundle of hosts. Make sure you include the "#!" in the first line of the template to avoid mis-interpretation of shell syntax, eg. sh interprets as csh.

If you even compile open source tools before, you will normally run:
./configure; make; make install
What ./configure does is to work out all the details and create the 'Makefile' by substituting all the @VARIABLES@ in the 'Makefile.in' template. Below is the first few lines of 'Makefile.in' in Tcl 8.4

VERSION                 = @TCL_VERSION@
MAJOR_VERSION           = @TCL_MAJOR_VERSION@
MINOR_VERSION           = @TCL_MINOR_VERSION@
PATCH_LEVEL             = @TCL_PATCH_LEVEL@

prefix                  = @prefix@
exec_prefix             = @exec_prefix@
bindir                  = @bindir@
libdir                  = @libdir@
includedir              = @includedir@
mandir                  = @mandir@

Next time when you compile open source tools, take a look under the hood to understand how the thing works.

Labels: ,

0 Comments:

Post a Comment

<< Home