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.
    – l0b0
    Sep 5 '19 at 19:07
  • I can confirm zgrep (gzip) 1.9 (Debian buster) is good and zgrep (gzip) 1.6 (Debian stretch) is bad.
    – Freddy
    Sep 5 '19 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.
    – Freddy
    Sep 5 '19 at 19:37
  • Thanks to l0b0 and Freddy for pointing to the correct solution. Sep 5 '19 at 20:07
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 <eggert@cs.ucla.edu>
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.