Sometimes you just want to bail out of a script when something happens. Let's say we're testing the output of some "chk" command and want to exit if it says "No". That's easy: we just add "chk | grep -q "No" && exit 0" to our script. If that "chk" spits out "No", our script is done right then and there - no more of it will be executed.
But what if you want to do more? You want to say "Sorry, Dave, I can't do that" and then exit. This won't work :
chk | grep -q "No" && echo "Sorry Dave"; exit 0; echo "rest of script"
That's always going to exit, whether "chk" says "No" or "Fooey"
You can do this:
chk | grep -q "No" && echo "Sorry Dave" && exit 0; echo "rest of script"
That's kind of a cheat - it relies on your echo "Sorry Dave" returning success. Nothing wrong with that but it gets kind of clumsy when you want to make a bunch of other things happen after the apology. It gets impossible if you have to use something that won't necessarily return success:
chk | grep -q "No" && echo "Sorry Dave" && ls /adir && exit 0; echo "rest of script"
That only works if /adir exists. There has to be an easier way.
Wait, can't we put things in lists? Sure we can! How about:
chk | grep -q "No" && ( echo"Sorry Dave";echo "You too, John";exit; ) echo "rest of script"
That almost works - it apologizes to both people, but it doesn't exit. How can that be?
The exit doesn't happen because that kind of list runs in a sub-shell. It's exactly like putting echo"Sorry Dave";echo "You too, John";exit; in another script called "sorry" and running:
chk | grep -q "No" && sorry echo "rest of script"
Fortunately, bash has a solution:
chk | grep -q "No" && { echo"Sorry Dave";echo "You too, John";exit; } echo "rest of script"
The braces tell bash to execute the list right here in the same shell. The exit will work properly now. Don't leave off the ";" though; you'll get " syntax error: unexpected end of file" if you do.
There are other ways to do this.
result=`chk | grep -q "No"` if [ $result ] then echo"Sorry Dave" echo "You too, John"; exit fi echo "rest of script"
Or this way:
function apology { echo "Sorry, Dave." echo "You too, John" exit } chk | grep -q "No" && apology echo "rest of script"
As a general rule, you shouldn't put exits in functions - doing that makes a complicated script harder to debug, especially because different languages treat an "exit" in different ways. The guy reading your script may think that the "exit" applies only to the function and not the whole script. Yes, he'd be wrong, but when you work with several languages it's easy to forget these details. Best not to put a root like that in his path.
Right this second, I can't think of another way to do this. Can you?
Got something to add? Send me email.
More Articles by Anthony Lawrence © 2011-04-28 Anthony Lawrence
If debugging is the process of removing bugs, then programming must be the process of putting them in. (Edsger W. Dijkstra)
Printer Friendly Version
Breaking out of a script Copyright © March 2009 Tony Lawrence
Have you tried Searching this site?
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.
Contact us
Printer Friendly Version