APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

Breaking out of a script

© March 2009 Anthony Lawrence

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 ] 
  echo"Sorry Dave"
  echo "You too, John";
echo "rest of script"

Or this way:

function apology {
  echo "Sorry, Dave."
  echo "You too, John"

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.

(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> Breaking out of a script

Inexpensive and informative Apple related e-books:

Sierra: A Take Control Crash Course

Take Control of OS X Server

Digital Sharing Crash Course

Take Control of Parallels Desktop 12

Take Control of Upgrading to El Capitan

More Articles by © Anthony Lawrence

Printer Friendly Version

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

If debugging is the process of removing bugs, then programming must be the process of putting them in. (Edsger W. Dijkstra)

Linux posts

Troubleshooting posts

This post tagged:





Unix/Linux Consultants

Skills Tests

Unix/Linux Book Reviews

My Unix/Linux Troubleshooting Book

This site runs on Linode