Search code examples
bashunixgrepexit-code

Check grep return code


My script contains following sets in place:

set -o errexit
set -o pipefail
set -o nounset

Now I would like o grep (not sed, awk, etc) for letter A in file b, and add the result to the file c:

grep A b >> C

The problem is that grep exits with RC 1 if no A is found in b file, which in my case is fine as I don't see that as an issue. In that case I wrapped grep command in a function and run:

function func_1() {
  grep A b >> C
}

if func_1; then
  echo "OK"
else
  echo "STILL OK"
end

Everything works great, but soon I realised it would be nice to catch RC=2 (grep failure). How can I do that?


Solution

  • I don't see how that protects you from the effects of set -e

    I think you'll need need a wrapper function that disables errexit for the duration, something like:

    function func_2 {
        set +o errexit
        func_1 "$@"
        rc=$?
        set -o errexit
        echo "$rc"
    }
    
    case $(func_2) in
        0) echo "success" ;;
        1) echo "not found" ;;
        2) echo "trouble in grep-land" ;; 
    esac
    

    Reading closely the documentation for set -e, you can handle commands with non-zero exit status in certain situations. However, you function cannot return a non-zero exit status:

    #!/bin/bash
    set -o errexit
    
    function mygrep {
        local rc=0
        # on the left side of ||, errexit not triggered
        grep "$@" >/dev/null || rc=$?
    #     return $rc         # nope, will trigger errexit
        echo $rc
    }
    
    echo "test 1: exit status 0"
    mygrep $USER /etc/passwd
    
    echo "test 2: exit status 1"
    mygrep foobarbaz /etc/passwd
    
    echo "test 2: exit status 2"
    mygrep $USER /file_does_not_exist
    
    echo done
    

    outputs

    test 1: exit status 0
    0
    test 2: exit status 1
    1
    test 2: exit status 2
    grep: /file_does_not_exist: No such file or directory
    2
    done