Find(1): test 'A' pass but test 'A -o B' fails

This function doesn’t print out anything;

skyrimse_testroot() {
    local directory="$1"
    find "$directory" 
        ( -type f -ipath "${directory}/data/scripts/*.pex"        ) -o 
        ( -type d -ipath "${directory}/data/meshes"               ) 
        -print -quit
}

But this one does (I removed the second test group);

skyrimse_testroot() {
    local directory="$1"
    find "$directory" 
        ( -type f -ipath "${directory}/data/scripts/*.pex"        )  
        -print -quit
}

$1 is an absolute path, so is the starting point and the -ipath arguments.

Based on my humble knowledge of boolean logic, chaining more OR clauses to a positive expression should not make that expression evaluate negatively. Either find is broken or I got something wrong, and I suspect one option more than the former.

Asked By: B. Bergeron

||

I wouldn’t say broken but the precedence in find tests can be very surprising especially the way actions are involved.

From https://manpages.debian.org/stable/findutils/find.1.en.html

NON-BUGS

Operator precedence surprises

The command find . -name afile -o -name bfile -print will never print
afile because this is actually equivalent to find . -name afile -o ( -name bfile -a -print ). Remember that the precedence of -a is higher than that of -o and when there is no operator specified between tests,
-a is assumed.

So in your example your current parentheses are not necessary because ‘and’ has higher precedence but you must add them around all tests.

find "$directory" 
        '(' 
            -type f -ipath "${directory}/data/scripts/*.pex" 
            -o 
            -type d -ipath "${directory}/data/meshes" 
        ')' 
        -print -quit
Answered By: Paul Pazderski
Categories: Answers Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.