59

I'm struggling to see why the following is returning a code of 1.

echo 'Total' | grep -c No
0

So "No" doesn't exists in "Total". But then looking up its return code I'm seeing it as 1.

echo $?
1

Why is return code showing up as 1? Is there a way to get around this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
difurious
  • 1,523
  • 3
  • 19
  • 32
  • 4
    `grep` will return zero only when some string is matched. this rule is applicable for `grep -c` as well. – P.... Feb 15 '17 at 14:00

2 Answers2

74

According to man grep page, -c flag is for

-c, --count Suppress normal output; instead print a count of matching lines for each input file.

So what you are seeing is the count of the match and not to be confused with the exit code of the grep match. The code 1 is because of no lines matching from the input.

Have a look at the other case,

echo 'No' | grep -c No
1

echo $?
0

Also to read on EXIT CODES on man grep page,

EXIT STATUS Normally the exit status is 0 if a line is selected, 1 if no lines were selected, and 2 if an error occurred.

Inian
  • 80,270
  • 14
  • 142
  • 161
  • 15
    You will have to remove the `-e` from the bash Shebang `#!/bin/bash -e` comment, otherwise the grep exit 1 status will still cause your script to exit. – b01 Jul 27 '18 at 22:49
61

The exit code is 1 because nothing was matched by grep.

EXIT STATUS The exit status is 0 if selected lines are found, and 1 if not found. If an error occurred the exit status is 2. (Note: POSIX error handling code should check for '2' or greater.)

The output is zero because the count of 'Total' is zero. This due to the -c option:

-c, --count Suppress normal output; instead print a count of matching lines for each input file. With the -v, --invert-match option (see below), count non-matching lines. (-c is specified by POSIX.)

If you would like to force an exit code of 0, you can just append || true to your command:

echo 'Total' | grep -c No || true
codeforester
  • 39,467
  • 16
  • 112
  • 140
rutgerm
  • 721
  • 4
  • 4