Search code examples
bashgrepexit-code

Why is Gnu grep exit status always 0 on standard input?


On a bash command line in Ubuntu 14.04 :

echo "z" | grep -e 'x' ; echo $PIPESTATUS

always displays 0, even though, obviously, there's no "x" in "z". But:

echo "z" > /tmp/z
grep -e 'x' /tmp/z ; echo $PIPESTATUS 

works as I expect, returning 1 if the pattern is 'x' (as shown), and 0 if the pattern is 'z'.

Why?


Solution

  • PIPESTATUS is actually a BASH array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline.

    To print all the exit statuses, you need to use it as:

    echo "z" | grep -e 'x' ; echo ${PIPESTATUS[@]}
    0 1
    

    Where 0 is exit status of first echo command and 1 is the exit status of grep command.

    When you use echo $PIPESTATUS it just prints first element of array.

    To check the grep command status you don't even need to use PIPESTATUS.

    You should just use $?:

    echo "z" | grep -q 'x' ; echo $?
    1