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.

I wrote a setup script to install my prefered programs and settings after I got a new server.

apt-get install git
git clone http://me@myvimsetting.github.com .vim
ln -s .vimrc .vim/vimrc
...

But if something wrong happens during setup, how can I interrupt the setup script, and log the error(s)? For example, if github server is down, it's obviously useless to create a symbolic link to non-existed vimrc.

(or you have a better approach to initialize a server?)

share|improve this question
    
as @cjc said, chef is good if you are doing this a lot. –  Tom H Mar 23 '12 at 21:22
add comment

3 Answers

On a basic level, you can do things like redirect STDERR to a text file to log errors

git clone http://me@myvimsetting.github.com .vim 2>> ~/logs/vim-error.txt

Or in this particular example you could do an if statement

if [ -f .vimrc ] ## -f means "if file exists"
then
ln -s .vimrc .vim/vimrc
fi

Or after the git clone command you could check its exit status and if it's not 0 exit the script

if [ $? -ne 0 ]
then
exit 1
fi

All of my scripts are n00b level scripts and I've found these things will generally do what I need them to do.

share|improve this answer
1  
Yeah, checking the return status is useful. although a chain tests for non-zero status e.g. git clone http://me@myvimsetting.github.com .vim 2>> ~/logs/vim-error.txt || exit 99 would exit immediately if the git clone failed. –  Tom H Mar 23 '12 at 21:25
    
Thanks. I didn't know about ||. It would seem that && and || are the cleaner and more efficient options for my examples above. –  Safado Mar 23 '12 at 21:55
    
for the truly lazy, like myself, there is the set -o errexit which just exits on any non-caught non-zero status. but if you want to catch a fail you can slap "|| true" on the end to prevent the exit like this false || true –  Tom H Mar 23 '12 at 22:46
    
somehow some madness has set in because bash is now my weapon of choice for this sort of thing... ;-) –  Tom H Mar 23 '12 at 22:46
add comment

sure, thats the approach i use. However the principle you are looking for is idempotence and failure tolerance, which is that the script should not mess anything up, and can degrade elegantly. For creating the link, test whether the file exists first like so;

[ -s .vimrc ] && ln -s .vimrc .vim/vimrc

but its also handy to check that the link doesn't exist already; (ie skip if it exists)

[ -s .vimrc ] && [ ! -L .vim/vimrc ] && ln -s .vimrc .vim/vimrc

which basically says, check if the file exists and that it is non-zero, then only create the link if its not there already. There are quite a few file tests supported by bash described in the manual here

There are also usually short cut version of these, but I might as well show you full version first...

typical its handy to run an apt-get update first, to refresh the package lists...

Obviously there is no point trying to install git if its already installed, (though you might want to upgrade it

dpkg -l git >/dev/null || apt-get -q -y install git

If you just want the latest version, whatever, then don't both with the test and apt will only upgrade if there is one available;

 apt-get -q -y install git

I tend to use full paths in installer scripts, just to remind myself and make sure it doesn't do anything silly. eg

 #explicitly set the full path somewhere
 HOME=/home/tomh

 #and then double check, partcular if you are about to do something descructive
[ "$HOME" == "" ] && exit 99
[ -s $HOME/.vimrc ] && ln -s $HOME/.vimrc $HOME/.vim/vimrc

for the getting the file from git I would shoot for something like this;

if [ ! -d $HOME/.vim ]; then
cd $HOME
git clone http://me@myvimsetting.github.com .vim
else
cd $HOME/.vim
git pull
fi

check any of that before you use, i didn't test it

share|improve this answer
add comment

Chef, specifically chef-solo. Might be a bit of upfront setup, but once you have your cookbooks in place, new machine setup is basically enumerating the run_list for the server.

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.