4

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://[email protected] .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?)

1
  • as @cjc said, chef is good if you are doing this a lot.
    – Tom
    Mar 23, 2012 at 21:22

3 Answers 3

5

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

git clone http://[email protected] .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.

4
  • 1
    Yeah, checking the return status is useful. although a chain tests for non-zero status e.g. git clone http://[email protected] .vim 2>> ~/logs/vim-error.txt || exit 99 would exit immediately if the git clone failed.
    – Tom
    Mar 23, 2012 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, 2012 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
    Mar 23, 2012 at 22:46
  • somehow some madness has set in because bash is now my weapon of choice for this sort of thing... ;-)
    – Tom
    Mar 23, 2012 at 22:46
2

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://[email protected] .vim
else
cd $HOME/.vim
git pull
fi

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

1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .