Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

cog (4665)

Journal of cog (4665)

Wednesday May 26, 2004
04:35 AM

Bash pipe exit codes

[ #18948 ]
So the question for the day is:

The exit code of a pipe is the result of the last executed command...

How do I know if any of the other commands originated an exit code different from 0? :-| Is this possible at all?

Some examples (with Perl ;-) ):

  • perl -e 'exit 3' | perl -e 'exit 2'
  • exit code => 2
  • perl -e 'exit 3' | perl -ne 'exit 2'
  • exit code => 3
  • perl -e 'exit 3' | perl -e 'exit 0'
  • exit code => 0

How can I get that 3 on the first and last examples? :-|

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • ... but you can solve this at least one of two ways. You can build the pipe yourself and check the exit code from all of the children. You can also try something like this from the command line...

    perl -e 'exit 1';rc1=$? | perl -e 'exit 0'; rc2=$? echo $rc1

    ... which seems to work for me.

    • The 'echo $rc1' should appear on the following line, obviously...
    • I get the idea...

      However, it seems parens are needed, no? Something like:

      (perl -e 'exit 1';rc1=$?) | perl -e 'exit 0';rc2=$?

      Because otherwise the second command on the pipe will only get the result of the atribution to rc1 ;-)

      But that works :-)

      Thanks a lot for the idea :-)

      • Ugh, and it's not even Monday. Yeah I think you are right. As you can tell my shell scripting ability is pretty rusty -- probably since I use perl a lot more often nowadays...
      • Nope. When a command is a pipeline, all but the last portions are run by a forked copy of the original shell - the assignment to rc1 will be done by that sub-shell and will not affect any setting of rc1 in the parent shell. You have to report the status out of band and catch it separately.

        (perl -e 'exit 1'; echo rc1=$? >> /tmp/status ) |
        (perl -e 'exit 5'; echo rc2=$? >> /tmp/status ) |
        perl -e 'exit 99'
        `cat /tmp/status`

        (You can echo those status assignments to stderr or stdout and catch