I like to do a lot of error checking in bash. There are so many easy ways to destroy a system; something like this:
cd /nonexistentdirectory
rm -f *
can just ruin your whole day. So I usually do something simple, like:
cd /nonexistentdirectory||exit 1
rm -f *
That works. But if you've got it in the middle of a script, you'll never know about it. The obvious thing to do is to mail yourself a message.
cd /nonexistentdirectory||(echo "$0 failed chdir"|mailx tim;exit 1)
This works fine. That is, it emails me a nice error message - and then proceed to destroy all of my files. See, it tosses up a subshell - a completely separate instance of bash. Here's a little experiment.
TESTVAL="testing"
echo "testval before=$TESTVAL"
cd /nonexistentdirectory||(TESTVAL="not a test";echo $TESTVAL)
echo "testval after=$TESTVAL"
Running it shows:
testval before=testing
/usr/local/scripts/verify_full: line 25: cd: /nonexistentdirectory: No such file or directory
testval=not a test
testval after=testing
/usr/local/scripts/verify_full: line 25: cd: /nonexistentdirectory: No such file or directory
testval=not a test
testval after=testing
So my variable gets changed to what I want it to - and then as soon as I drop out of that subshell, it changes back. My 'exit 1' had the no effect at all - it droped me out of the subshell (which I was about to exit anyway) back to the main shell, and then proceeded to destroy all of my files.
Curly braces to the rescue.
cd /nonexistentdirectory||{ TESTVAL="not a test";echo "testval=$TESTVAL"; }
/usr/local/scripts/verify_full: line 25: cd: /nonexistentdirectory: No such file or directory
testval=not a test
testval after=not a test
Now, the 'exit 1' really will drop you out of the whole script. Your files are saved!
One gotcha - note the semicolon before the closing brace. If you forget to put it there, you will search for a long time trying to find out why the script is failing.
No comments:
Post a Comment