Search code examples
perlpipeexit-code

Propagate exit status across pipes


I would like to use a small script to do some cosmetic work to the output of my gcc.

So I use this command:

 mygcc foo.c 2>&1 | myscript.pl

Basically my script does things like this:

$error = 0;
while(<>)
{
    s/^"(.*)"\s*,\s*line\s*(\d+)\s*:\s*(cc\d+)\s*:/colored("[$3]", 'bold red').colored(" $1", 'red').":".colored("$2", 'yellow')/ge;
    s/ \^/colored(" ^", 'yellow')/e;
    s/(error:.*$)/colored($1, 'red')/ge;
    s/(warning.*$)/colored($1, 'yellow')/ge;
    print;
    $error = -1;
}    

Unfortunately the exit code from gcc is not correctly propagated through the pipe. What I need to do is to get the exit code from gcc and write it back from my script.

Without this, make won't correctly stop the build process in case of an error.

How can I achieve this?


Solution

  • Try using a sub shell:

    ( mygcc foo.c; echo "gcc returned $?" ) |& myscript.pl
    

    The ( cmd ) construct is used to launch cmd in a sub-shell. Your current shell will fork itself, and the commands will be executed by the child shell. It's an easy way to run multiple commands and have the output fed to a pipe.

    The $? variable is the exit status of the last command.

    The cmd1 |& cmd1 construct is equivalent to cmd1 2>&1 | cmd2