8

I'm a nube to more than just bash, however; I've written a bash script that will execute my cmake, make, and c++ executable.

#! /bin/bash
cmake .
make
./pcl_visualizer_demo   <-- This is my executable

This works great except when my code fails to compile it executes the old executable and leaves me with a mess. I was hoping to put the output of make into an if statement that only runs the executable when make is successful. I've tried a great many bash things from other posts here on stackoverflow. Some of the problems seem to be that the output of make is not a string for example:

OUTPUT = make
echo $OUTPUT

gives:

[100%] Built target pcl_visualizer_demo

But fails to work with:

if [`expr match "$OUTPUT" '[100%] -eq 5]; then ./pcl_visulizer_demo; fi

Not to mention I think there may be more than one thing wrong with this line. I also tried:

if [diff <(echo "$OUTPUT") <(echo '[100%] Built target pcl_visualizer_demo' -n]; then ./pcl_visulizer_demo; fi

Again it could be that I'm not implementing it right. Any help

arco444
  • 22,002
  • 12
  • 63
  • 67
CheesePita
  • 93
  • 1
  • 8

4 Answers4

28

Just check the exit code of make:

cmake . || exit 1
make || exit 1
./pcl_visualizer_demo 
choroba
  • 231,213
  • 25
  • 204
  • 289
  • 1
    Thanks it works great! Sadly I'm not allowed to up vote you because I have no reputation :(. – CheesePita Jun 18 '15 at 16:27
  • 1
    Great, thanks God that somebody didn't rely on the google comment under the question. :) Can you explain a bit how this works? `make` will return 0 when everything is fine and because of short circuiting `exit` won't be executed? In the failure case it will, but what is that `1` after `exit`? The return value of the script? – gsamaras Jul 10 '15 at 20:56
  • 1
    @gsamaras: Yes, yes, yes. :-) – choroba Jul 10 '15 at 21:00
10

You could use

set -e

at the beginning of your shell script

#!/bin/bash
set -e
cmake .
make
./pcl_visualizer_demo

From 'help set'

-e  Exit immediately if a command exits with a non-zero status.

Which by default means: on any error

Trencher
  • 121
  • 1
  • 7
5

You should probably check the exit code of make e.g.

if [ $? -eq 0 ]
then
  echo "Successfully made"
else
  echo "Could not compile" >&2
fi

and exit appropriately. By convention, an exit code of 0 indicates success. If you have multiple executables and you want to bail out if any return a non-zero exit code, you can tell bash to do just that with the -e option e.g.

  #!/usr/bin/bash -e

Just make sure that the executables (make and cmake) follow this convention. See here for more information on exit codes.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • Thanks. Sadly as it turns out make returns 0 weather or not it fails. choroba suggested the or command and it works great. I'm not allowed to up vote you because I have no reputation :(. – CheesePita Jun 18 '15 at 16:28
  • I would expect make *not* to return 0 upon failure, and the || construct above relies on the exit code being not 0. So I would recheck your exit code (I think Choroba's solution would work nicely, of course) – Brian Agnew Jun 18 '15 at 16:42
  • Yes you are correct. Your method also works. I used echo $? to test the output of make and it gives me 0 both when it works and when it fails. Why am I getting this printed to the terminal yet your code works when pasted in full? – CheesePita Jun 18 '15 at 16:56
0

You could try to determine what the 'exit status' of your previous bash command was using '$?'. Usually, a build that did not succeed will exit with a non zero status. Double check that this is true in your case by echo-ing '$?'

Then use an normal if statement to proceed correctly.

$? reads the exit status of the last command executed. After a function returns, $? gives the exit status of the last command executed in the function. This is Bash's way of giving functions a "return value." . . .
After a script terminates, a $? from the command-line gives the exit status of the script, that is, the last command executed in the script, which is, by convention, 0 on success or an integer in the range 1 - 255 on error.

Source: http://www.tldp.org/LDP/abs/html/exit-status.html

Ben Behar
  • 364
  • 3
  • 12
  • What a useful command. Thanks. Sadly as it turns out make returns 0 weather or not it fails. choroba suggested the or command and it works great. I'm not allowed to up vote you because I have no reputation :(. – CheesePita Jun 18 '15 at 16:25
  • As Brian Agnew pointed out. The output of make is not always 0. Somehow when I echo $? I always get 0. I'm not sure why. – CheesePita Jun 18 '15 at 17:04