Who needs clean configuration? Swapping server.xml So I'm working on a project that sometimes requires me to switch my server configuration. This is due to some circumstances with database drivers and names that are "too expensive to fix" ...

That made me think though: "Why do I always copy these files around manually?"

I decided I won't and wrote this small script to help me:

#!/bin/bash

if [ $# != 1 ]
    then 
    echo "you must provide a configuration to switch to"
    exit
fi;

if [ -a $TOMCAT_HOME/conf/server_$1.xml ]
    then
    rm $TOMCAT_HOME/conf/server.xml
    cp $TOMCAT_HOME/conf/server_$1.xml $TOMCAT_HOME/conf/server.xml
else
    echo "given configuration was not found. did not make any changes."
fi;

exit 0


Usage is dead simple: I made this available system-wide and can just call:

switch-config postgres


or 

switch-config firebird


To make changes happen.

This is built for my personal convenience, so please ignore the incredibly bad error messages, also the (nonexistent) directory structure is for simple convenience. Comments like "move the different configurations somewhere else" don't help me.

In any case, what can I improve?
Method

I'd suggest, instead of rm-ing and cp-ing, keeping each configuration set as named and symlinking to them as needed.

This gives you a couple of benefits:


You can tell which the current one is without opening the file, just using ls -l:


lrwxrwxrwx 1 user group 4 Jul 29 07:12 server.xml -&gt; config-for-blah.xml


Changes are (sort-of) atomic: rm and cp take time, while over-writing a symlink with a symlink is as close to instant as you can reasonably make it.
You can move the actual files anywhere later and just update the symlinks: version-control it in a repo directory, put configuration sets into separate directories, whatever.


Replacing the rm and cp in your current script, that'd be:

ln -sf "$TOMCAT_HOME/conf/server_$1.xml" "$TOMCAT_HOME/conf/server.xml"


(You need -f, or else ln will complain that the link you're trying to create already exists.)

You should also detect whether the main commands have completed successfully, probably using something like:

if [ $? -ne 0 ];
    then
    echo "Oops." &gt;&amp;2
    exit 1
fi


Scripting


Quote your filenames. This helps avoid accidents where variables are mis-set.
Check your test types. In [ $# != 1 ], $# is being referenced as a number, but != is for strings. Use -ne for numbers. (This is just a good habit to get into.)
You don't need the semicolons after the fi.
Error messages should usually go to stderr: echo "Error" &gt;&amp;2
When detecting an error and exiting, exit with an status other than 0: this lets you easily detect problems when using the script. (c.f. the check in the method section above.)
Maybe do something to avoid command aliases. Sometimes aliases for commands like rm, cp, and ln can get into scripts by accident and make scripts break. You can avoid this by making sure your use of them doesn't trigger alias expansion for the commands, either by quoting, escaping, or using the full path.