How do you chain commands in BASH or CSH?

I often need to run several commands which can take an hour or more and I won’t necessarily be present the entire time. It is nice to be able to run a command, and if it is successful, then run another; However, if one command fails, then stop the flow.  This article will tell you how to do this on the command line.

Chaining On Success

Perhaps you want to build, and then test. It would be annoying if the tests ran even if the build failed.

To chain the commands so subsequent commands will only run if the preceding command was successful (returned a zero):

make && run_test && echo "SUCCESS"

Chaining On Failure

To run a command followed by another command, only if the first command failed, then use:

make || echo "BUILD FAILED!"

You can also combine them:

(sh -c "exit 0" && sh -c "exit 1") && echo "SUCCESS" || echo "FAIL"

With Email

This becomes very powerful if you send yourself an email with the results so you know when a run completes and the result, e.g.

(sh -c "exit 0" && sh -c "exit 1") && mailx -s "Build: SUCCESS" $USER < /dev/null || mailx -s "Build: FAIL" $USER < /dev/null

Chaining Regardless

To run a command followed by another command, regardless of the return code, then use:

make; echo "BUILD DONE - make returned code: $?"

How does this work?

It is easiest to think of this all simply as Boolean logic. Boolean comparisons will only evaluate until the result can be determined.

On Linux a return code from a command of “0” means success. All other return codes are regarded as failures. This can be confusing because normal Boolean logic uses a 1 for true, e.g.

1 && 1 == 1, Evaluates the first and second expression
1 && 0 == 0, Evaluates the first and second expression
0 && 1 == 0, Only evaluates the first expression
0 && 0 == 0, Only evaluates the first expression

However, for our return codes this looks like:

exit 0 && exit 0 == Success, Executes the first and second command
exit 0 && exit 1 == Fail, Executes the first and second command
exit 1 && exit 0 == Fail, Only executes the first command
exit 1 && exit 1 == Fail, Only executes the first command

We can use a similar example for OR:

1 || 1 == 1, Only evaluates the first expression
1 || 0 == 1, Only evaluates the first expression
0 || 1 == 1, Evaluates the first and second expression
0 || 0 == 0, Evaluates the first and second expression

With return codes this looks like:

exit 0 || exit 0 == Success, Only executes the first command
exit 0 || exit 1 == Success, Only executes the first command
exit 1 || exit 0 == Success, Executes the first and second command
exit 1 || exit 1 == Fail, Executes the first and second command

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s