I have a directory with the following files and a .git directory, e.g.

├── .git
│   ├── branches
│   ├── packed-refs
│   └── refs
├── readme.md
├── server_build.sh
└── tags

If I run GNU find command with the -prune test, find prints the directory which is prune'd:

% find . -name '.git' -prune

If add another OR option, then the directory which is pruned not longer appears in the output:

% find . -name '.git' -prune -o -name '*.md' -print

In this case, both -name '.git' and -name '*.md' tests must be returning true, it can't be possible that adding another OR test suddenly makes the -name '.git' -prune test untrue.
Is there some implicit switch being added to the first statement?
In other words is find turning

find . -name '.git' -prune


find . -name '.git' -prune -print

at run time? and the implicit -print is taken away when the next test when is added?
Why doesn't find print the -prune'd directory when another "-or" test is applied?

  • try find . \( -name '.git' -prune -o -name '*.md' \) -print also there is some discussion on this in man find just before EXIT STATUS – Sundeep Jul 19 '16 at 6:10
  • find . -name '.git' -prune prints .git because there is no other action. On the other hand, find . -name '.git' -prune -o -name '*.md' -print is actually equivalent to find . \( -name '.git' -prune \) -o \( -name '*.md' \) -a -print , and -prune no longer prints anything since there is another action. – Satō Katsura Jul 19 '16 at 6:23
  • @SatoKatsura I thought -prune was an action, and therefore the implicit -print would not be used here. – the_velour_fog Jul 19 '16 at 6:26
  • 2
    From the manual: If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true. – Satō Katsura Jul 19 '16 at 6:30
  • @SatoKatsura I think thats actually the answer – the_velour_fog Jul 19 '16 at 6:33
find . -name '.git' -prune

is the same as

find . -name '.git' -prune -print

so it prunes and then prints

find . -name '.git' -prune -o -name '*.md' -print

is the same as

find . \( -name '.git' -prune -true \) -o \( -name '*.md' -print \)

so it does first clause, if it does prune then it does true (prune returns true), and does not do right hand side of -o

These will always print

find . \( -name '.git' -prune -o -name '*.md' \) -print
find . -name '.git' -prune -print -o -name '*.md' -print
| improve this answer | |
  • ah I think I understand. So its possible to perform TWO actions on matching files. so ` find . -name '.git' -prune -print` is the same as ` find . -name '.git' -a -prune -a -print` .? and -print would not happen if prune returned false? – the_velour_fog Jul 19 '16 at 8:49
  • @the_velour_fog yes. – ctrl-alt-delor Jul 19 '16 at 9:09
  • thanks, although in your answer where you say find . -name '.git' -prune -o -name '*.md' -print is the same as find . \( -name '.git' -prune -true \) -o \( -name '*.md' -print \) and and does not do right hand side of -o. the right hand does get run - its the only statement that produces output. i.e. output is: ./readme.md – the_velour_fog Jul 19 '16 at 9:33
  • 1
    Yes rhs should get evaluated when not -name '.git'. – ctrl-alt-delor Jul 21 '16 at 11:36

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