0

I have a function that seems to break when I turn on errors with set -e. I suspect that it is working as intended but I can't see what I'm doing wrong.

Here is the function:

#!/usr/bin/env bash

set -e

my_function() {
    base_dir="/tmp/test"
    if [ ! -d $base_dir ]; then
        echo "Creating $base_dir"
        mkdir -p $base_dir
        touch $base_dir/some-file.txt
    fi

    is_edited=$(grep "foo" $base_dir/some-file.txt)

    if [ ! -z $is_edited  ]; then
        cd $base_dir
        echo "Doing stuff"
        docker run --rm debian ls
    fi

    echo
    echo "Done"
    echo
}

my_function

With set -e flipped on, the function returns seemingly without hit the echo statements. With set -e turned off, the echo statements get hit. What is happening and how do I fix this?

jmreicha
  • 3,155
  • 7
  • 32
  • 39
  • 1
    `grep` returns a non-zero exit code if it doesn't find a match. This will be treated as an error by `set -e`. – Barmar Jan 16 '16 at 00:24
  • @Barmar Ah, that makes sense. Maybe there is a better approach to this than using grep or is there a better way to handle the return value for it? – jmreicha Jan 16 '16 at 00:30

2 Answers2

3

Try using:

is_edited=$(grep "foo" $base_dir/some-file.txt || test $? -eq 1)

The exit status of grep is 0 if it found a match, 1 if it didn't find a match, and 2 if it got an actual error. So if there's no match for foo in the file, it will be considered an error, and set -e will terminate the script. The above code translates 1 to a success, so the script will only terminate if grep gets a real error.

If you don't care about terminating the script if grep gets an error, you could just use

if grep -1 "foo" $base_dir/some-file.txt ; then
    ...
fi

The -q option makes it not print the matching line, just set its exit status based on whether it found a match.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

as fmtn07 stated, it's with the return code.

try changing the grep statement from:

is_edited=$(grep "foo" $base_dir/some-file.txt)

to:

is_edited=$(grep "foo" $base_dir/some-file.txt || true)

yftse
  • 183
  • 6