4

Setup

echo "abc" >/tmp/foo1
echo "def" >/tmp/foo2
cp /tmp/foo1 /tmp/gzfoo1
cp /tmp/foo2 /tmp/gzfoo2
gzip /tmp/gzfoo*

grep exit status with multiple files and one match is 0

grep -q abc /tmp/foo[12]
echo $?
0

zgrep exit status with multiple unzipped files and one match is 1

zgrep -q abc /tmp/foo[12]
echo $?
1

zgrep exit status with multiple zipped files and one match is 1

zgrep -q abc /tmp/gzfoo[12].gz
echo $?
1

I do see that zgrep is a shell script. And it does seem like if any grep returns non-zero, zgrep returns non-zero as well. Here's my paraphrased excerpt from zgrep:

res=0
for input_file
do
  # ... run grep on input_file ...
  r=$?
  ...
  test $res -lt $r && res=$r
done
exit $res

zgrep version is (ancient) 1.3.12:

$ zgrep --version
zgrep (gzip) 1.3.12
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.

Also happens with zgrep (gzip) 1.6:

$ /<other_zgrep_path/bin/zgrep --version
zgrep (gzip) 1.6
Copyright (C) 2010-2013 Free Software Foundation, Inc.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.

$ /<other_zgrep_path/bin/zgrep -q abc /tmp/gzfoo[12].gz
$ echo $? 
1

Question: Is there a bug in zgrep? Should it be fixed?

Edit: Found a newer machine with zgrep/gzip 1.8 and it doesn't have this problem. So, it seems like my machine is just old. Here's what it looks like on the newer machine:

: zgrep --version
zgrep (gzip) 1.8
Copyright (C) 2010-2016 Free Software Foundation, Inc.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.

: zgrep -q abc /tmp/foo[12]
: echo $?
0

Hacky Workaround to avoid old/buggy zgrep:

: ( gzcat -f /tmp/foo[12] | grep -q abc ) >&/dev/null 
: echo $?
0
4
  • I can't reproduce with zgrep (gzip) 1.10. zgrep -q abc /tmp/foo[12] and zgrep -q abc /tmp/gzfoo[12].gz both return exit code 0. Please add the output of zgrep --version and type zgrep to your question. Commented Sep 5, 2019 at 19:07
  • I can confirm zgrep (gzip) 1.9 (Debian buster) is good and zgrep (gzip) 1.6 (Debian stretch) is bad. Commented Sep 5, 2019 at 19:21
  • There were a lot of changes from 1.6 to 1.7 regarding the exit code, see fossies.org/diffs/gzip/1.6_vs_1.7/zgrep.in-diff.html (variable res=0 vs. res=1 and the changes at the bottom of the page). Seems it was fixed there. Commented Sep 5, 2019 at 19:37
  • Thanks to l0b0 and Freddy for pointing to the correct solution. Commented Sep 5, 2019 at 20:07

1 Answer 1

2

You can get source code from https://savannah.gnu.org/git/?group=gzip. Return code was changed in commit d2a1928e5534017456dc8a3b600ba0b30cce4a6e:

commit d2a1928e5534017456dc8a3b600ba0b30cce4a6e
Author: Paul Eggert <[email protected]>
Date:   Thu Jun 12 18:43:08 2014 -0700

    zgrep: exit with status 0 if a file matches and there's no trouble

    Reported by Pavel Raiskup in: http://bugs.gnu.org/17760
    * zgrep.in (res): Treat exit status 0 to be greater than 1.
    Also, exit immediately on software configuration error.

Commit message contains a link to bug report: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=17760

You can easily check it yourself. With zgrep built from the above commit:

$ /media/data/gzip-install-newer/bin/zgrep --version
zgrep (gzip) 1.6.17-d2a1
Copyright (C) 2010-2014 Free Software Foundation, Inc.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.
$ /media/data/gzip-install-newer/bin/zgrep -q abc /tmp/foo[12]
$ echo $?
0

With zgrep built from the previous commit:

$ /media/data/gzip-install/bin/zgrep --version
zgrep (gzip) 1.6.16-ed8c
Copyright (C) 2010-2014 Free Software Foundation, Inc.
This is free software.  You may redistribute copies of it under the terms of
the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
There is NO WARRANTY, to the extent permitted by law.

Written by Jean-loup Gailly.
$ /media/data/gzip-install/bin/zgrep -q abc /tmp/foo[12]
$ echo $?
1
2
  • Here's the d2a1928e5534017456dc8a3b600ba0b30cce4a6e diff. Commented Sep 5, 2019 at 20:02
  • Thanks for detailed reply! Glad to see it's already fixed and just that I'm on an old version. Commented Sep 5, 2019 at 20:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.