Search code examples
linuxbashawkteepipestatus

Getting the exit status of a nested command inside a redirect attached to tee


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?


Solution

  • 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.