Subject: bug#28105: closed (Re: bug#28105: Inconsistent exit code with --files-without-match)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 17 Aug 2017 21:23:02 +0000

Your bug report

#28105: Inconsistent exit code with --files-without-match

which was filed against the grep package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
28105: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=28105
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#28105: Inconsistent exit code with --files-without-match
From: Paul Eggert <[email-masked]>
To: Anthony Sottile <[email-masked]>
Cc: [email-masked]
Date: Thu, 17 Aug 2017 14:21:59 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Thanks for the pointer. It looks to me like git-grep's behavior is 
better than grep's, so I installed the attached.

>From 92526f7246464825c5547ceb08e01433e035c867 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 17 Aug 2017 14:15:35 -0700
Subject: [PATCH] grep: -L exits with status 0 if a file is selected

Problem reported by Anthony Sottile (Bug#28105).
* NEWS, doc/grep.texi (Exit Status), src/grep.c (usage): Document this.
* src/grep.c (grepdesc): Implement it.
* tests/skip-read: Test it.
---
 NEWS            | 5 +++++
 doc/grep.texi   | 3 +++
 src/grep.c      | 6 +++---
 tests/skip-read | 2 +-
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 81f51b5..9ed78fb 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU grep NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Changes in behavior
+
+  The --files-without-match (-L) option now causes grep to succeed
+  when a file is listed, instead of when a line is selected.  This
+  resembles what git-grep does.
 
 * Noteworthy changes in release 3.1 (2017-07-02) [stable]
 
diff --git a/doc/grep.texi b/doc/grep.texi
index 24800c9..865acf1 100644
--- a/doc/grep.texi
+++ b/doc/grep.texi
@@ -1067,6 +1067,9 @@ and only when @env{POSIXLY_CORRECT} is not set.
 
 Normally the exit status is 0 if a line is selected, 1 if no lines
 were selected, and 2 if an error occurred.  However, if the
+@option{-L} or @option{--files-without-match} is used, the exit status
+is 0 if a file is listed, 1 if no files were listed, and 2 if an error
+occurred.  Also, if the
 @option{-q} or @option{--quiet} or @option{--silent} option is used
 and a line is selected, the exit status is 0 even if an error
 occurred.  Other @command{grep} implementations may exit with status
diff --git a/src/grep.c b/src/grep.c
index a37e87b..5847c7a 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -1863,11 +1863,11 @@ grepdesc (int desc, bool command_line)
         fflush_errno ();
     }
 
-  status = !count;
+  status = !count != (list_files == LISTFILES_NONMATCHING);
 
   if (list_files == LISTFILES_NONE)
     finalize_input (desc, &st, ineof);
-  else if (list_files == (status ? LISTFILES_NONMATCHING : LISTFILES_MATCHING))
+  else if (status == 0)
     {
       print_filename ();
       putchar_errno ('\n' & filename_mask);
@@ -1994,7 +1994,7 @@ Context control:\n\
       printf (_("\
 When FILE is '-', read standard input.  With no FILE, read '.' if\n\
 recursive, '-' otherwise.  With fewer than two FILEs, assume -h.\n\
-Exit status is 0 if any line is selected, 1 otherwise;\n\
+Exit status is 0 if any line (or file if -L) is selected, 1 otherwise;\n\
 if any error occurs and -q is not given, the exit status is 2.\n"));
       emit_bug_reporting_address ();
     }
diff --git a/tests/skip-read b/tests/skip-read
index 1eef87e..3c32c48 100755
--- a/tests/skip-read
+++ b/tests/skip-read
@@ -15,7 +15,7 @@ for opts in '-m0 y' '-f /dev/null' '-v ""'; do
       eval returns_ 1 grep -l $opts $matcher /dev/null > out || fail=1
       compare /dev/null out || fail=1
     done
-    eval returns_ 1 grep -L $opts $matcher /dev/null > out || fail=1
+    eval grep -L $opts $matcher /dev/null > out || fail=1
     compare exp out || fail=1
   done
 done
-- 
2.13.5

Subject: Inconsistent exit code with --files-without-match
From: Anthony Sottile <[email-masked]>
To: [email-masked]
Date: Tue, 15 Aug 2017 15:01:13 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Given the exit code of `grep` vs. `grep -v`, I expect similar results
when comparing `grep -l` and `grep -L` (`--files-with-matches` /
`--files-without-match`)

For at least `grep` / `grep -v` / `grep -l` when the "search" is
successful, it exits `0` and when the search is unsuccessful it exits
`1`.  `grep -L` (`--files-without-match`) does not follow this pattern
which I believe to be an oversight / bug.

Consider the following:

$ echo hello > f

# Search is for "hello", it matches so exit code is 0
$ grep hello -- f; echo $?
hello
0
# Search is for "hi", it fails to match so the exit code is 1
$ grep hi -- f; echo $?
1

# Search is for not "hi", it matches so exit code is 0
$ grep -v hi -- f; echo $?
hello
0
# Search is for not "hello", it fails to match so the exit code is 1
$ grep -v hello -- f; echo $?
1

# Search is for filenames containing hello, it matches so exit code is 0
$ grep -l hello -- f; echo $?
f
0
# Search is for filenames containing hi, it fails to match so exit code is 1
$ grep -l hi -- f; echo $?
1

# Search is for filenames not containing hi, this search is successful
**but it exits 1**
$ grep -L hi -- f; echo $?
f
1
# Search is for filenames not containing hello, this search fails
**but it exits 0**
$ grep -L hello -- f; echo $?
0

Anthony