Why does the behaviour of find(1) differ when explicitly adding -print?

Posted on

Problem :

The man page for find(1) says:

If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.

However, there seems to be a difference between these two expressions:

$ find . -path '*fo*' -prune -o -type f -print
$ find . -path '*fo*' -prune -o -type f

Why is ./foo included in the output of the latter?

I created the example directory tree structure for the above with:

$ cd $(mktemp -d)
$ mkdir foo
$ mkdir bar
$ touch foo/quux
$ touch bar/xzyzzy

The output of find --version for me is:

find (GNU findutils) 4.4.2`

Solution :

Oh, I think I’ve worked it out on my own…

In the former case, the -print is performed only when the first condition (-path '*fo*') is not true because of the short-circuit behaviour of -o.

However, in the second case, the implicit -print is done when the whole expression is true – that will be the case when -path '*fo*' is true or -type f is true. In other words, the two commands in my question are equivalent to:

$ find . ( -path '*fo*' -prune ) -o ( -type f -print )

… and:

$ find . ( -path '*fo*' -prune -o -type f ) -print

I think, anyway 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *