>From 02f00ec50e820b9320af66ee7bb47bab36184f96 Mon Sep 17 00:00:00 2001 From: Ulrich Eckhardt Date: Mon, 14 Feb 2022 19:23:10 +0100 Subject: [PATCH 1/4] grep: implement `--pipe` option * src/grep.c: Implement `--pipe` option, which does not indicate matches or lack thereof in the exit code but only filters the input into the output. --- src/grep.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/grep.c b/src/grep.c index 9c933e4..2260d7d 100644 --- a/src/grep.c +++ b/src/grep.c @@ -498,7 +498,8 @@ enum INCLUDE_OPTION, LINE_BUFFERED_OPTION, LABEL_OPTION, - NO_IGNORE_CASE_OPTION + NO_IGNORE_CASE_OPTION, + PIPE_OPTION }; /* Long options equivalences. */ @@ -543,6 +544,7 @@ static struct option const long_options[] = {"null", no_argument, NULL, 'Z'}, {"null-data", no_argument, NULL, 'z'}, {"only-matching", no_argument, NULL, 'o'}, + {"pipe", no_argument, NULL, PIPE_OPTION}, {"quiet", no_argument, NULL, 'q'}, {"recursive", no_argument, NULL, 'r'}, {"dereference-recursive", no_argument, NULL, 'R'}, @@ -1078,6 +1080,7 @@ static enum static int out_file; static int filename_mask; /* If zero, output nulls after filenames. */ +static bool out_pipe; /* --pipe: Don't set exit status depending on match. */ static bool out_quiet; /* Suppress all normal output. */ static bool out_invert; /* Print nonmatching stuff. */ static bool out_line; /* Print line numbers. */ @@ -2017,6 +2020,7 @@ Output control:\n\ ")); printf (_("\ -o, --only-matching show only nonempty parts of lines that match\n\ + --pipe only filter, do not set exit value depending on found matches\n\ -q, --quiet, --silent suppress all normal output\n\ --binary-files=TYPE assume that binary files are TYPE;\n\ TYPE is 'binary', 'text', or 'without-match'\n\ @@ -2698,6 +2702,10 @@ main (int argc, char **argv) only_matching = true; break; + case PIPE_OPTION: + out_pipe = true; + break; + case 'q': exit_on_match = true; exit_failure = 0; @@ -3008,5 +3016,9 @@ main (int argc, char **argv) status &= grep_command_line_arg (*files++); while (*files != NULL); - return errseen ? EXIT_TROUBLE : status; + if (errseen) + return EXIT_TROUBLE; + if (out_pipe) + return EXIT_SUCCESS; + return status; } -- 2.32.0 >From e930e55fd34f02bd9959148c1d43a3fe521e2169 Mon Sep 17 00:00:00 2001 From: Ulrich Eckhardt Date: Mon, 14 Feb 2022 21:36:39 +0100 Subject: [PATCH 2/4] tests: add tests for --pipe * tests/pipe: Add new test file exercising the `--pipe` option. * tests/Makefile.am: Register new test file. --- tests/Makefile.am | 1 + tests/pipe | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100755 tests/pipe diff --git a/tests/Makefile.am b/tests/Makefile.am index a211cb6..ae8ffc8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -148,6 +148,7 @@ TESTS = \ pcre-w \ pcre-wx-backref \ pcre-z \ + pipe \ posix-bracket \ prefix-of-multibyte \ proc \ diff --git a/tests/pipe b/tests/pipe new file mode 100755 index 0000000..9c789bb --- /dev/null +++ b/tests/pipe @@ -0,0 +1,42 @@ +#!/bin/sh +# tests for --pipe commandline option +# A missing or found match does not influence the exit status. + +. "${srcdir=.}/init.sh" +path_prepend_ ../src + +require_timeout_ + +failures=0 + +# should return 0 even though it doesn't find a match in stdin +echo -n '' | LC_ALL=C timeout 10s grep --pipe abcd +if test $? -ne 0 ; then + echo 'Status: Wrong status code, test #1 failed' + failures=1 +fi + +# should return 0 even though it doesn't find a match in the input file +echo -n '' > in +LC_ALL=C timeout 10s grep --pipe abcd in +if test $? -ne 0 ; then + echo 'Status: Wrong status code, test #2 failed' + failures=1 +fi + +# should return 0 even though it doesn't find a match in stdin +echo -n '' | LC_ALL=C timeout 10s grep --invert-match --pipe abcd +if test $? -ne 0 ; then + echo 'Status: Wrong status code, test #3 failed' + failures=1 +fi + +# should return 0 even though it doesn't find a non-match in the input file +echo -n '' > in +LC_ALL=C timeout 10s grep --invert-match --pipe abcd in +if test $? -ne 0 ; then + echo 'Status: Wrong status code, test #4 failed' + failures=1 +fi + +Exit $failures -- 2.32.0 >From 7bcc7fb748be62bf87be15e5d1f78d54b6c10823 Mon Sep 17 00:00:00 2001 From: Ulrich Eckhardt Date: Tue, 15 Feb 2022 20:46:12 +0100 Subject: [PATCH 3/4] doc: update manpage * doc/grep.in.1: Add --pipe manpage documentation. --- doc/grep.in.1 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/grep.in.1 b/doc/grep.in.1 index 372b892..89aa5fc 100644 --- a/doc/grep.in.1 +++ b/doc/grep.in.1 @@ -357,6 +357,14 @@ non-matching lines. Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line. .TP +.B \-\^\-pipe +For use in pipelines. Just apply the configured input filters but +don't set any exit status depending on found matches. Not matching +the search pattern is not always an error, so don't report it like +one. The use is shell scripting (e.g. Bash's `set -o pipefail`), +which otherwise requires explicitly checking for exit codes 0 or 1 +in the middle of a pipeline. +.TP .BR \-q ", " \-\^\-quiet ", " \-\^\-silent Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, @@ -971,7 +979,11 @@ or or .B \-\^\-silent is used and a line is selected, the exit status is 0 even if an error -occurred. +occurred. With the +.B \-\^\-pipe +option, the exit status is 2 when an error occurred and 0 otherwise. +Other @command{grep} implementations may exit with status greater than +2 on error. . .SH ENVIRONMENT The behavior of -- 2.32.0 >From 4fd80ac450dc2429dd03e803c9a8a729307ba069 Mon Sep 17 00:00:00 2001 From: Ulrich Eckhardt Date: Tue, 15 Feb 2022 20:57:12 +0100 Subject: [PATCH 4/4] doc: update texinfo * doc/grep.texi: Add --pipe documentation. --- doc/grep.texi | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/grep.texi b/doc/grep.texi index 37ef839..b2a98bd 100644 --- a/doc/grep.texi +++ b/doc/grep.texi @@ -387,6 +387,16 @@ Output lines use the same delimiters as input, and delimiters are null bytes if @option{-z} (@option{--null-data}) is also used (@pxref{Other Options}). +@item --pipe +@opindex --pipe +@cindex --pipe +For use in pipelines. Just apply the configured input filters but +don't set any exit status depending on found matches. Not matching +the search pattern is not always an error, so don't report it like +one. The use is shell scripting (e.g. Bash's `set -o pipefail`), +which otherwise requires explicitly checking for exit codes 0 or 1 +in the middle of a pipeline. + @item -q @itemx --quiet @itemx --silent @@ -1093,8 +1103,9 @@ 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{-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 -greater than 2 on error. +occurred. With the @option{--pipe} option, the exit status is 2 +when an error occurred and 0 otherwise. Other @command{grep} +implementations may exit with status greater than 2 on error. @node grep Programs @section @command{grep} Programs -- 2.32.0