1

I'd like to conditionally execute a command in a gnu makefile, based on the return value of another command.

To be specific, something like this:

lsmod | grep -q pfc && sudo rmmod pfc

If the current list of modules as output by lsmod contains pfc, remove it. This works, with the small problem that if the grep command fails (module not present) the whole pipeline returns non-zero, which causes the command to be interpreted as failed, but in fact this is a success.

I could just add a ; true at the end to always force it to success, but this won't catch failures in the rmmod command!

I'd like something that mostly portably across sh implementations, but technically I guess I'm using dash since that's where sh points on Ubuntu.

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • Because that pipeline _unconditionally_ returns true. In particular if `rmmod` fails we want to return false, but the above returns true. – BeeOnRope Sep 02 '17 at 21:37
  • This is only a problem if you are using `set -e`, which is a bad idea precisely because it assumes all non-zero exit statuses indicate an error. – chepner Sep 07 '17 at 22:16
  • @chepner - I am not using `set -e`, but the calling application (`gmake`) treats non-zero returns as errors, which makes sense. – BeeOnRope Sep 07 '17 at 22:20

1 Answers1

4

You could just handle the expected failure by cleaning the exit value with a nop command like echo -n:

if lsmod | grep -q pfc; then sudo rmmod pfc; else echo -n; fi

Should the output be missing the nop command is executed and the whole line returns with $?=0.

Edit:
The simpler nop's that were suggested would look like:

if lsmod | grep -q pfc; then sudo rmmod pfc; else true; fi

resp

if lsmod | grep -q pfc; then sudo rmmod pfc; else :; fi
yacc
  • 2,915
  • 4
  • 19
  • 33