The following works as expected:[pitserver ~]% sudo find /home/pitserver/operator -uid 11 -exec ls -nld {} +drwxr-xr-x 2 11 28 4096 Jan 30  2006 /home/pitserver/operator-rw------- 1 11 28   32 Oct  3  2005 /home/pitserver/operator/.amandahosts-rw------- 1 11 28  700 Jan 30  2006 /home/pitserver/operator/.viminfo-rw------- 1 11 28   65 Jan 30  2006 /home/pitserver/operator/.XauthorityI would expect the following to list every file, but instead it lists every file except .amandahosts:[pitserver ~]% sudo find /home/pitserver/operator -name '.amandahosts' -or -uid 11 -exec ls -nld {} +        drwxr-xr-x 2 11 28 4096 Jan 30  2006 /home/pitserver/operator-rw------- 1 11 28  700 Jan 30  2006 /home/pitserver/operator/.viminfo-rw------- 1 11 28   65 Jan 30  2006 /home/pitserver/operator/.XauthorityWhy is this the case?
Why does the -or flag to GNU find cause my expression to evaluate in an unexpected way?
find
According to man find, juxtaposition (which is an implied and operator) takes precendence over the -or operator, so one might expect the arguments to be evaluated like so:( -name '.amandahosts' -or -uid 11 ) and ( -exec ls -ld {} + )In fact, if I add the parens to the find command, it works as expected:[pitserver ~]% sudo find /home/pitserver/operator '(' -name '.amandahosts' -or -uid 11 ')' -exec ls -nld {} +drwxr-xr-x 2 11 28 4096 Jan 30  2006 /home/pitserver/operator-rw------- 1 11 28   32 Oct  3  2005 /home/pitserver/operator/.amandahosts-rw------- 1 11 28  700 Jan 30  2006 /home/pitserver/operator/.viminfo-rw------- 1 11 28   65 Jan 30  2006 /home/pitserver/operator/.XauthorityHowever, find actually interprets the arguments like this:( -name '.amandahosts' ) or ( -uid 11 -exec ls -ld {} + )As you can see here:[pitserver ~]% sudo find /home/pitserver/operator -name '.amandahosts' -or '(' -uid 11 -exec ls -nld {} + ')'drwxr-xr-x 2 11 28 4096 Jan 30  2006 /home/pitserver/operator-rw------- 1 11 28  700 Jan 30  2006 /home/pitserver/operator/.viminfo-rw------- 1 11 28   65 Jan 30  2006 /home/pitserver/operator/.XauthorityWhat's happening here is that the or is short-circuiting.  The second part of the '-or' (-uid 11 -exec ls -ld {} +) is evaluated only if the first part (-name '.amandahosts') evaluates to false.  So find will only run -exec ... if the file is not named '.amandahosts'.  One way to see how this works is to observe that the following succeeds:[pitserver ~]% sudo find /home/pitserver/operator -name '.amandahosts' -exec ls -nld {} + -or -uid 11 -exec ls -nld {} +-rw------- 1 11 28 32 Oct  3  2005 /home/pitserver/operator/.amandahostsdrwxr-xr-x 2 11 28 4096 Jan 30  2006 /home/pitserver/operator-rw------- 1 11 28  700 Jan 30  2006 /home/pitserver/operator/.viminfo-rw------- 1 11 28   65 Jan 30  2006 /home/pitserver/operator/.XauthorityThe best way to solve this problem seems to be to always use parens when using an or operator, as this gives exactly the desired behavior:'(' -name '.amandahosts' -or -uid 11 ')' -exec ls -nld {} +