bashpipebackticks

bash pipestatus in backticked command?


in bash, if I execute a couple of commands piped together inside of backticks, how can I find out the exit status of the first command?

i.e. in this case, I am trying to get the "1". which I can get via PIPESTATUS[0] if I am not using backticks, but which doesn't seem to work when I want to saving the output:

## PIPESTATUS[0] works to give me the exit status of 'false':
$ false | true;
$ echo $? ${PIPESTATUS[0]} ${PIPESTATUS[1]};
0 1 0

## doesn't work:
$ a=`false | true`;
$ echo $? ${PIPESTATUS[0]} ${PIPESTATUS[1]};
0 0

More generally, I am trying to accomplish: save the last line of the output of some program to a variable, but be able to tell if the program failed:

$ myvar=` ./someprogram | tail -1 `;
$ if [ "what do i put here" ]; then echo "program failed!"; fi

Ideally I'd also like to understand what is going on, not just what the answer is.

Thanks.


Solution

  • Try to set pipefail option. It returns the last command of the pipeline that failed. One example:

    First I disable it:

    set +o pipefail
    

    Create a perl script (script.pl) to test the pipeline:

    #!/usr/bin/env perl
    
    use warnings;
    use strict;
    
    if ( @ARGV ) { 
        die "Line1\nLine2\nLine3\n";
    }
    else {
        print "Line1\nLine2\nLine3\n";
    }
    

    Run in command-line:

    myvar=`perl script.pl | tail -1`
    echo $? "$myvar"
    

    That yields:

    0 Line3
    

    It seems correct, let see with pipefail enabled:

    set -o pipefail
    

    And run the command:

    myvar=`perl script.pl fail 2>&1 | tail -1`
    echo $? "$myvar"
    

    That yields:

    255 Line3