1

I have this command:

coverage report | tee >(grep TOTAL | awk '{exit (int($4) >= 75)?0:1}') && (exit ${PIPESTATUS[0]})

which reports the code coverage and then prints the output to stdout and redirects that same output to a grep + awk, which basically checks whether the code coverage covers less or more than 75. Finally, there is an exit in a subshell, which I pretend to use in my CI/CD pipeline.

The problem is that my CI/CD always completes successfully, which shouldn't happen as the code coverage is less than 75% in my tests. That means that the PIEPSTATUS isn't returning what I'm expecting it to return (awk's exit code).

Where is the problem? What am I doing wrong?

alexandernst
  • 14,352
  • 22
  • 97
  • 197
  • Why are you running `exit ${PIPESTATUS[0]}` inside a subshell `(...)`? – codeforester Oct 24 '18 at 00:47
  • Because I want to set the exit code, so that the CI/CD will act upon it. – alexandernst Oct 24 '18 at 00:48
  • Possible duplicate of [Get exit status of process that's piped to another](https://unix.stackexchange.com/q/14270/56041), [Pipe output and capture exit status in Bash](https://stackoverflow.com/q/1221833/608639), etc. – jww Oct 24 '18 at 11:22

1 Answers1

6

Exit status of

command | tee >(...)

will be the exit status of tee, regardless of what happens inside the process substitution >(...). That's the reason your code is not working.

You can achieve your goal without having to use process substitution, like this:

coverage report | awk '{print} /TOTAL/ { pcnt=$4 } END {exit (int(pcnt) >= 75) ? 0 : 1}')
  • {print} prints all the lines
  • /TOTAL/ ... grabs the percentage and saves it in pcnt
  • END ... exits code based on pcnt

This will not only print all the lines emitted by coverage report, it would also make sure that the exit code of pipeline reflects the coverage percentage logic.

codeforester
  • 39,467
  • 16
  • 112
  • 140