Search code examples
bashshellmakefileterminal

Bash script print error and exits or continues


I am new to bash and shell scripting. I have a command that I want to execute in my Makefile. But if the command throws and error than I want the Makefile to throw and error and exit. Else I want it to continue to the next commands.

Here is the psuedocode of what I am trying to achieve:

some-makefile-command:
    if command fails execution:
         print the command's error message
         exit
    else:
         execute other commands

Solution

  • If you want to an arbitrary if statement in a makefile, you have to be aware that every recipe line in a makefile target is run in a new shell. So for example:

    all:
        if [ $blah ]; then
            echo something
        fi
    

    has three separate recipe lines. The first line if [ $blah ]; then would be passed to a shell instance, which would then complain that it's not a complete statement (it would not pass the other lines to that instance of the shell), and it would fail. The fix is to use concatenation (a trailing \ at the end of each line) to make all of the lines into a single line as so:

    all:
        if [ $blah ]; then \
            echo something; \
        fi
    

    This would pass if [blah]; then echo something; fi to the shell instance, which the shell instance could understand, and would be able to process.

    Notice the ; after echo something -- because you're concatenating lines, and there's no actual newline after echo something, you need the ; to delimit the action from the fi statement.

    --- EDIT ----

    outside of this, you could just do:

    some-makefile-command:
        command
        #other commands
    

    if recipe command fails (returns non-zero), then make will stop processing the rule, and exit (no need to explicitly call exit). Otherwise it will continue to run the rest of the commands. If you want to output something special if the command fails you could do:

    some-makefile-command:
        command || echo "something" && false
    

    Notice that the recipe as a whole must fail for make to stop processing, and because echo "..." always returns true, you need the && false at the end to make the entire statement return false if command fails