39

I was reading the grep man page and came across the -q option, which tells grep to "not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected."

I don't understand why this could be desirable or useful behavior. In a program who's reason d'etre seems to be read from stdin, process, write to stdout, why would I want to silence it completely?

In what case would silencing a program whose goal it is to output things be useful? Why would someone want to entirely ignore errors and force a successful return code?

Thanks!

mrflash818
  • 930
  • 13
  • 24
jsarbour
  • 928
  • 1
  • 8
  • 20
  • 6
    Besides its output streams, an executable has another way to communicate information : its exit status. For `grep` for instance it would be `0` if it matched something and something else otherwise. You could rely on this status to check whether a file contains a string or not, and if that's all you care about then it makes sense to suppress the output – Aaron May 16 '19 at 13:56
  • 1
    Also, consider the `-c` option. Sometimes you don't care about *which* lines match, just *how many* match. From there, it's easier to imagine a further simplification where you don't even care *exactly* how many lines match, just the difference between 0 and >0 matches. – chepner May 16 '19 at 14:01
  • 4
    Moreover, this is a lot faster than a regular grep invocation, since it can exit immediately when the first match is found, rather than needing to unconditionally read (and write) to the end of file. – Charles Duffy May 16 '19 at 15:30
  • So exit status would be output even with the -q option provided? – jsarbour May 17 '19 at 19:40
  • 1
    -q only tells grep to not output anything to "standard output" but EVERY program that runs must have a return-value (at least in Unix-systems). Languages like C allow for the omission of explicitly writing it out, but the program will still have a return-value. – ABaumstumpf Jan 21 '22 at 07:46

2 Answers2

57

The exit status of grep doesn't necessarily indicate an error ; it indicates success or failure. grep defines success as matching 1 or more lines. Failure includes matching zero lines, or some other error that prevented matching from taking place in the first place.

-q is used when you don't care about which lines matched, only that some lines matched.

if grep -q foo file.txt; then
    echo "file.txt contains foo"
else
    echo "file.txt does not contain foo"
fi
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    To make sure I understand; this is for when it's called as a function, and you want its return code? – jsarbour May 17 '19 at 16:35
  • Not sure what you mean by "as a function", but in the example shown, you aren't interested in seeing the lines containing the word `foo`, only in knowing they exist. – chepner May 17 '19 at 17:46
  • And how would you know if they exist if you silence all output from grep? – jsarbour May 17 '19 at 19:39
  • 3
    Because the exit status is different, and that's what `if` looks at. – chepner May 17 '19 at 20:41
  • Okay, Thanks! Looks like I should go read up on exit statuses. Do you know any good documentation that would help? – jsarbour May 18 '19 at 22:19
2

Here's an example of grep -q: scanning the output of a command for a particular value, then performing an action if the value is found:

if docker context ls | grep -q dm-manager; then
  docker context rm dm-manager
fi

if the list of docker contexts contains the string dm-manager then remove docker context dm-manager.

Nic
  • 1,518
  • 12
  • 26