Subject: bug#63780: Reversing the grep message output type matching binary files (without the -a option added) changed from stdout to stderr

From: Paul Eggert <[email-masked]>
Date: Wed, 31 May 2023 17:38:10 -0700

On 2023-05-30 14:01, [email-masked] wrote:

> Why is finding the desired text in a binary file not a "positive finding"
> as it is in a text file?

But it is a positive finding. Grep exits with zero status, which is a 
positive result.

There is no perfect solution here. In the old days when 'grep' reported 
the situation to standard output, this made stdout confusing and we got 
bug reports about it. Jim's earlier email 
<https://bugs.gnu.org/63780#14> briefly summarizes some of those issues. 
When we changed 'grep' to report the situation to standard error, we 
then got complaints the other way. In cases like this we just have to 
use our best judgment.

> The point of the grep is to find the regex in matching files -- there is
> no differentiation between text and binary files in the concept of
> searching for a string in all files.

If you merely want to find matching files, use 'grep -l'. Then the 
problem doesn't come up.

> This gets especially hairy when various utilities (gnu, et al.) classify
> ill-formatted text files as 'binary' because they don't fit some definition
> of a text file.

Yes, and 'grep' must be particularly careful since it's so widely used 
and if it outputs random binary data to the screen it can screw up the 
user's terminal. This can even be a security issue. This is an important 
reason why 'grep -a' is not the default (though -a is there if you want 
it - presumably you know what you're doing if so).

> Noting a match (which is what grep should do), shouldn't be considered 
> an error

It's not considered an error. It's merely a diagnostic sent to stderr. 
They're not the same thing.

In that sense, it's like the diagnostic "recursive directory loop" from 
'grep -R'. That diagnostic is also sent to stderr, but it is not 
considered an error and it does not affect the exit status. It's sent to 
stderr because sending it to stdout would likely cause more trouble than 
it would cure.