GNU bug report logs -
#79728
Flag to return 0 if no match
Previous Next
To reply to this bug, email your comments to 79728 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 13:44:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Alejandro Colomar <alx <at> kernel.org>:
New bug report received and forwarded. Copy sent to
bug-grep <at> gnu.org.
(Thu, 30 Oct 2025 13:44:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi!
I'm working on a script around grep(1) which calls
set -Eeuo pipefail;
trap 'exit 2;' ERR;
...
| xargs grep regex;
I'd like to be able to return 2 on any errors, like grep(1) does, which
is why I'm using the trap(1). However, I need to workaround the fact
that grep(1) returns non-zero for no matches. What I'm doing at the
moment is
...
| {
xargs grep regex || true;
};
However, this also hides errors from xargs, which I'd like to keep.
Alternatively, I could use something like
...
| while read -r f; do
grep regex "$f" || true;
done;
However, the performance would drop to unusable levels (I experienced
a slow down of 100x in a quick test I did), so it's not an option.
Would you mind adding an option to coerce grep(1) to return 0 on zero
matches?
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[signature.asc (application/pgp-signature, inline)]
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 15:03:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 79728 <at> debbugs.gnu.org (full text, mbox):
Of course,
xargs grep regex
is tricky to handle because you want grep to produce exit statuses that
xargs will process to produce the exit status you want.
I think this will get the effect you want:
... | xargs bash -c "grep $regex ; [[ \$? -le 1 ]]'
and it runs grep no more times than "xargs grep" will.
Dale
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 15:12:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 79728 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Dale,
On Thu, Oct 30, 2025 at 11:02:33AM -0400, Dale R. Worley wrote:
> Of course,
>
> xargs grep regex
>
> is tricky to handle because you want grep to produce exit statuses that
> xargs will process to produce the exit status you want.
>
> I think this will get the effect you want:
>
> ... | xargs bash -c "grep $regex ; [[ \$? -le 1 ]]'
>
> and it runs grep no more times than "xargs grep" will.
The problem with something based on
... | xargs bash -c ...
is that it would make it easy to inject commands in the bash script with
malicioulsy crafted files, right? It sounds scary.
Have a lovely day!
Alex
>
> Dale
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[signature.asc (application/pgp-signature, inline)]
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 16:56:02 GMT)
Full text and
rfc822 format available.
Message #14 received at 79728 <at> debbugs.gnu.org (full text, mbox):
On 10/30/25 09:11, Alejandro Colomar via Bug reports for GNU grep wrote:
>> ... | xargs bash -c "grep $regex ; [[ \$? -le 1 ]]'
>>
>> and it runs grep no more times than "xargs grep" will.
> The problem with something based on
>
> ... | xargs bash -c ...
>
> is that it would make it easy to inject commands in the bash script with
> malicioulsy crafted files, right?
If an attacker controls the regex you're already in trouble, because the
regex can be arbitrarily slow.
That being said, to avoid the regex being interpreted as shell code, you
can use something like this:
xargs sh -c 'grep -e "$0" -- "$@"; [ $? -le 1 ]' "$regex"
Admittedly a bit awkward, but it works now and it's portable to any
POSIX platform.
If this awkwardness is to be simplified it should be a patch to GNU
xargs not to grep, as programs like diff and cmp behave like grep and
it's not reasonable to add options to them all merely to work around an
xargs awkwardness.
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 17:24:02 GMT)
Full text and
rfc822 format available.
Message #17 received at 79728 <at> debbugs.gnu.org (full text, mbox):
Paul Eggert <eggert <at> cs.ucla.edu> writes:
> On 10/30/25 09:11, Alejandro Colomar via Bug reports for GNU grep wrote:
>>> ... | xargs bash -c "grep $regex ; [[ \$? -le 1 ]]'
>>>
>>> and it runs grep no more times than "xargs grep" will.
>> The problem with something based on
>> ... | xargs bash -c ...
>> is that it would make it easy to inject commands in the bash script
>> with
>> malicioulsy crafted files, right?
>
> If an attacker controls the regex you're already in trouble, because
> the regex can be arbitrarily slow.
Or exhaust your systems memory in the case of:
$ grep -E 'a+++++++++++++++++++++++++++++++++++++++' COPYING
Among many others. :)
Collin
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Thu, 30 Oct 2025 17:54:02 GMT)
Full text and
rfc822 format available.
Message #20 received at 79728 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi Paul,
On Thu, Oct 30, 2025 at 10:55:28AM -0600, Paul Eggert wrote:
> On 10/30/25 09:11, Alejandro Colomar via Bug reports for GNU grep wrote:
> > > ... | xargs bash -c "grep $regex ; [[ \$? -le 1 ]]'
> > >
> > > and it runs grep no more times than "xargs grep" will.
> > The problem with something based on
> >
> > ... | xargs bash -c ...
> >
> > is that it would make it easy to inject commands in the bash script with
> > malicioulsy crafted files, right?
>
> If an attacker controls the regex you're already in trouble, because the
> regex can be arbitrarily slow.
I'm not too worried about DoS. I was worried about remote code
execution. As in, I'll try to search for something in an arbitrary
directory, possibly controlled by a malicious actor, and file names or
contents could result in giving them control of my computer.
> That being said, to avoid the regex being interpreted as shell code, you can
> use something like this:
>
> xargs sh -c 'grep -e "$0" -- "$@"; [ $? -le 1 ]' "$regex"
Hmmm, it seems like what I want. Testing seems to work:
alx <at> devuan:~/tmp$ cat script
#!/bin/bash
set -Eeuo pipefail
echo foo bar baz | xargs sh -c 'echo "$0" -- "$@"; test $? -le 1;' "regex";
alx <at> devuan:~/tmp$ ./script
regex -- foo bar baz
>
> Admittedly a bit awkward, but it works now and it's portable to any POSIX
> platform.
This sounds quite robust; thanks!
> If this awkwardness is to be simplified it should be a patch to GNU xargs
> not to grep, as programs like diff and cmp behave like grep and it's not
> reasonable to add options to them all merely to work around an xargs
> awkwardness.
Makes sense; thanks! But I think I like your approach above; I don't
need simplifying it.
Have a lovely night!
Alex
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[signature.asc (application/pgp-signature, inline)]
Information forwarded
to
bug-grep <at> gnu.org:
bug#79728; Package
grep.
(Fri, 31 Oct 2025 00:49:02 GMT)
Full text and
rfc822 format available.
Message #23 received at 79728 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
[CC += Chet]
Hi Paul, Chet,
On Thu, Oct 30, 2025 at 06:53:22PM +0100, Alejandro Colomar wrote:
> > That being said, to avoid the regex being interpreted as shell code, you can
> > use something like this:
> >
> > xargs sh -c 'grep -e "$0" -- "$@"; [ $? -le 1 ]' "$regex"
I've applied the following commit:
commit 243666cfbab9d0bdb26424f1ba9cae8e5571cf68
Author: Alejandro Colomar <alx <at> kernel.org>
Date: Fri Oct 31 00:58:42 2025 +0100
src/bin/grepc: Handle xargs(1) errors properly
'xargs grep' is hard, because grep(1) exits with a status of 1 for no
match, which is not an error, but xargs(1) takes that as an error.
This trick with sh(1) was suggested by Paul, and nicely solves this
problem.
Link: <https://lists.gnu.org/archive/html/bug-grep/2025-10/msg00029.html>
Suggested-by: Paul Eggert <eggert <at> cs.ucla.edu>
Signed-off-by: Alejandro Colomar <alx <at> kernel.org>
diff --git a/src/bin/grepc b/src/bin/grepc
index 9f6de55d7..300a3b6c9 100755
--- a/src/bin/grepc
+++ b/src/bin/grepc
@@ -238,18 +238,16 @@ opts=($A $B $C $c $h $i $l -M $m $n);
if test -z "$*"; then
- pcre2grep "${opts[@]}" -f "$patterns" || true;
+ pcre2grep "${opts[@]}" -f "$patterns" || test $? -eq 1;
else
find "$@" -type f -print0 \
| if test -z "$c"; then
# shellcheck disable=SC2248 # $i may be -i or nothing.
- xargs -0 grep -lZPI $i -- "$identifier" || true;
+ xargs -0 sh -c 'grep -lZPI $i -e "$0" -- "$@" || test $? -eq 1;' "$identifier";
else
cat;
fi \
- | {
- xargs -0 pcre2grep "${opts[@]}" -f "$patterns" || true;
- };
+ | xargs -0 sh -c 'pcre2grep '"${opts[*]}"' -f "$0" -- "$@" || test $? -eq 1;' "$patterns";
fi \
| if test "$r" = 'yes'; then
perl -p -e 's/('"$identifier"')/\033[32m\1\033[0m/';
I've also had an idea for trying to keep the return value of 1 when
there are no matches. I could send a USR1 signal from grep(1).
I've written this proof-of-concept:
alx <at> devuan:~/tmp/g$ cat script2
#!/bin/bash
set -Eeuo pipefail;
shopt -s lastpipe;
trap 'exit 2;' ERR;
trap 'exit 1;' USR1;
find "$@" -type f \
| xargs bash -c 'grep -e "$0" -- "$@" || { test $? -eq 1 && kill -USR1 '"$$"'; };' 'foo';
However, if find(1) fails, grep(1) still sends this signal, and that
seems to have preference over the ERR trap.
$ ./script2 nonexistent; echo $?
find: ‘nonexistent’: No such file or directory
1
Do you know of any way to achieve that? I'd like to avoid sending other
signals from find, as the actual script is much more complex, and
sending signals from every command in the pipeline would be tedious (and
likely error prone).
Have a lovely night!
Alex
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[signature.asc (application/pgp-signature, inline)]
This bug report was last modified 5 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.