1
[kony@HOSTNAME testing]$ pwd
/apps/kony/fmw/testing
[kony@HOSTNAME testing]$ touch SCCS
[kony@HOSTNAME testing]$ touch NOT_SCCS
[kony@HOSTNAME testing]$
[kony@HOSTNAME testing]$ find . -name SCCS -prune -o -print
.
./NOT_SCCS
[kony@HOSTNAME testing]$

[kony@HOSTNAME testing]$

I am trying to understand how Logical operators work in find and how it affects prune.

  1. First Find command .

It will be treated as "find . -name SCCS -and -prune -o -print" . (An implicity -and between name and -prune action.

For every file and directory in current directory first "-name SCCS" condition will be checked. If name matches SCCS then the condition is true . Since First condition is true and "-and" is mentioned it will check next condition . next condition is "-prune" it will be evalvauted to true . So it will be like "find . true -and true -o -print" which means "find . true -o -print" . Since left condition is true and there is -or operation then next condition will be evaluated which is -print. This means that it should print file whose name is SCCS . Then why it is not printing. Am i understanding it wrongly.

rizwan
  • 339

1 Answers1

2

Am I understanding it wrongly?

You are.

Note: formally POSIX find does not define true as an operand. GNU find understands -true (with a leading dash) and -false. I will use these forms. I understand what you mean by true though.

I think you got the logic right up to (and including) find . -true -o -print. What you're missing is the fact an expression like subexpression1 -o subexpression2 or subexpression1 -a subexpression2 evaluates subexpression1 first and if its outcome is enough to tell the result of the entire expression then subexpression2 will not be evaluated. This means

-true -o -print

doesn't evaluate -print because sole -true is enough to tell the whole snippet evaluates to true. Similarly

-false -a -print

doesn't evaluate -print because sole -false is enough to tell the whole snippet evaluates to false.

The latter behavior is quite intuitive. E.g. with find . -name foo -print you don't want find to -print when -name foo is false. Realize it's a direct result of the general rule where subexpression1 -a subexpression2 does not evaluate subexpression2 if it's not necessary. Do not perceive find only as a tool to find or to print something. Think of it as of a tool to evaluate the given expression. Then it will be easy (or at least easier) to understand the behavior of -true -o -print and to treat -exec as a custom test (which is awesome, you can test virtually anything; example).

I have written one quite comprehensive answer about how find works. Unfortunately it's under a question that got little attention, so the answer itself got little attention too. But maybe you will find it useful.