GNU find의 "-or" 플래그로 인해 표현식이 예상치 못한 방식으로 평가되는 이유는 무엇입니까?

GNU find의 "-or" 플래그로 인해 표현식이 예상치 못한 방식으로 평가되는 이유는 무엇입니까?

다음은 예상대로 작동합니다.

[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

여기서 일어나는 일은 OR이 단락되었다는 것입니다. -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

이 문제를 해결하는 가장 좋은 방법은 "or" 연산자를 사용할 때 항상 괄호를 사용하는 것 같습니다. 이는 원하는 동작을 정확하게 제공하기 때문입니다.

'(' -name '.amandahosts' -or -uid 11 ')' -exec ls -nld {} +

관련 정보