Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grep exit codes in Makefile

I would like to check the result of a grep search in a Makefile. Contrary to this solution, I do not wish to use the shell command. Also, I don't want the Makefile to raise an error when grep do not find the string (exit code of 1 is treated as an error).

The following tries to ignore the error and check the exit code :

all:
    -grep term log* 
    echo $$?
    @case "$$?" in \
      0)\
    echo "found";; \
    *) \
    echo "not found";;\
    esac;

Unfortunately, the exit code is always 0.

like image 789
alex_reader Avatar asked Oct 25 '12 12:10

alex_reader


1 Answers

The separate lines of a series of actions in a makefile are normally executed in separate sub-shells. To code what you're after, then:

all:
    if grep term log*; \
    then echo found; \
    else echo not found; \
    fi

That's a single command; it tests the exit status of grep directly. Note the liberal use of semi-colons; that's necessary because it all gets flattened when passed to the shell. Note too that the - is not needed; the statement as a whole exits with status 0 because one of the echo commands is executed, succeeds, and that is the status returned from the sub-shell. But there's another part to the trick; IIRC, the script is invoked with /bin/sh -e so the script exits on the first error (non-zero) status from a shell command — except in explicit conditionals such as an if.

If you want to explicitly capture the status of grep (if only to be sure it's being done right), then:

all:
    -grep term log*; \
    status=$$?; echo $$status; \
    if [ $$status = 0 ]; \
    then echo found; \
    else echo not found; \
    fi

You probably need the - this time because the grep is not executed as part of a shell conditional and a non-zero exit status could trigger the -e processing. I don't recommend futzing with this.

You might note that you can do cd commands in an action and because each action is executed separately, you have to do it repeatedly.

install:  ${PROG}
    cd ${INSTBIN}; ${RM_F} ${PROG}
    ${CP} ${PROG} ${INSTBIN}
    cd ${INSTBIN}; ${CHOWN} ${OWNER}:${GROUP} ${PROG}; ${CHMOD} ${PERMS} ${PROG}

Yes, you can do it differently — I'm demonstrating a point, not advocating a style of installing programs.

like image 72
Jonathan Leffler Avatar answered Nov 02 '22 06:11

Jonathan Leffler