Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I found this weird behavior in find. Depending on the order of the parameters to find it finds different files.

For example, I have a directory tree with the following content.

├── configure.ac
├── Makefile.am
└── src
    ├── hello.c
    └── Makefile.am

if I run

find -name '*.cpp' -o -name '*.[chS]' -print0 | xargs -0 echo

It lists


And if I run

find -name '*.[chS]' -o -name '*.cpp' -print0 | xargs -0 echo

It doesn't list anything. Notice that the only thing I changed is the order of the file name.

Can anyone explain why the second command doesn't list any files?

share|improve this question
Almost duplicate of unix.stackexchange.com/q/102191/22565 – Stéphane Chazelas Apr 22 '14 at 15:35
up vote 3 down vote accepted

The -print0 action gets bound only to the second -name "filter" (test in find parlance), so it will only print out something if the second filter matches. This is because the default operator in the find expression is and, and binds tighter than or (-o). i.e. your second expression is evaluated as:

find -name '*.[chS]' -o \( -name '*.cpp' -print0 \) | xargs -0 echo

Try grouping the filters:

find \( -name '*.[chS]' -o -name '*.cpp' \) -print0 | xargs -0 echo

You could also do this if you felt like it:

find -name '*.[chS]' -print0 -o -name '*.cpp' -print0 | xargs -0 echo
share|improve this answer
Huh, that would also explain why giving -print0 as the first parameter lists all the files. Makes sense, but it's also a bit unexpected. Thanks a lot :) – Kotte Apr 22 '14 at 15:33

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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