I got a strange bug while using grep with bash on Redhat 7.0:
'grep -l pattern files' does not list matching files in the same order
as ls -1 !!! I don't know what the problem is related to grep? bash?
I have a directory containing files a.cc, a1.cc, b.cc, and b2.cc
that all contain the text "hello"
-- Running 'ls -1 *.cc' gives:
which is the correct lexicographic order
-- Running 'grep -l hello *.cc' gives:
THE ORDER IS NOT PRESERVED!!!
This problem is very annoying because the following commands:
grep -l hello *.cc > cc_files_containing_hello
ls *.cc | comm -23 - cc_files_containing_hello > \
which extract the list of files that do not contain pattern "hello"
will not work, because the file order in cc_files_containing_hello is
not the same as the one used by ls.
It is even more annoying because it was working on Redhat 6.0!
One thing that is surprising is that the problem does not occur
when I'm running the same commands under pdksh-5.2.14-8 !!!
Summary of the tests:
The problem occurs on
- Redhat 7.0 when running grep-2.4.2-4 under bash-2.04-11
Everything works fine on:
- Redhat 7.0 when running grep-2.4.2-4 under pdksh-5.2.14-8
- Redhat 6.0 when running grep-2.3-2 with under bash-1.14.7-16
- Redhat 6.0 when running grep-2.3-2 with under pdksh-5.2.14-1
- IRIX 6.x
- Solaris *
- HP-UX 10.20
Related problem (?)
Because I had some doubts about what Linux considers to be a lexicographic
order, I ran the following command on several Unix platforms:
ls -1 *.cc | sort
IRIX 6.x, Solaris 2.x and HP-UX 10.20 returned the correctly
Redhat 6.0 and Redhat 7.0 (gnu sort) returned the following
incorrect result (not a lexicographic order, thus incompatible
with ls! ):
There may be some relation ship with my problem here (?)
Is there a patch that fixes the problem?
Thanks for your help.
This is a feature, not a bug.
bash 2.x is locale aware, and sorts according to the locale, not according to
what C thinks, therefore a1 can come before a.
(*.cc is expanded by bash, put in the right order according to your locale,
then passed to grep, which preserves the order dictated by bash).
If you don't like this,
grep -l hello `ls -1 *.cc`
The latter may change to do just what you're seeing now in a later version of
export LC_COLLATE=c makes things work as expected.
Thanks a lot for your help