以下内容按预期工作:
[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/.Xauthority
我希望以下列出每个文件,但它列出了每个文件除了 .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/.Xauthority
为什么会这样呢?
答案1
根据man find
、并置(这是隐含的“and”运算符)优先于-or
运算符,因此人们可能期望参数的计算方式如下:
(-name '.amandahosts' -or -uid 11
) 和 (-exec ls -ld {} +
)
事实上,如果我将括号添加到 find 命令中,它会按预期工作:
[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/.Xauthority
然而, find 实际上是这样解释参数的:
(-name '.amandahosts'
) 或者 (-uid 11 -exec ls -ld {} +
)
正如你在这里看到的:
[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/.Xauthority
这里发生的情况是“或”短路了。-uid 11 -exec ls -ld {} +
评估“-or”( ) 的第二部分除非第一部分 ( -name '.amandahosts'
) 的计算结果为错误的。因此 find 仅-exec ...
当文件未命名时才会运行'.amandahosts'
。了解其工作原理的一种方法是观察以下内容是否成功:
[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/.amandahosts
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/.Xauthority
解决此问题的最佳方法似乎是在使用“或”运算符时始终使用括号,因为这恰好给出了所需的行为:
'(' -name '.amandahosts' -or -uid 11 ')' -exec ls -nld {} +