find -exec와 xargs를 통한 파이핑 사이의 다른 동작

find -exec와 xargs를 통한 파이핑 사이의 다른 동작

chmod go+w숨겨진 파일이 포함된 특정 폴더에서 재귀적으로 실행하고 싶어서 먼저 시도해 봤습니다.

find . -name ".*" -o -name "*" -exec chmod go+w {} \;

하지만 숨겨진 파일에는 영향을 미치지 않는 것으로 나타났습니다. 내 자신을 확인하기 위해 방금 달렸습니다.

find . -name ".*" -o -name "*"

숨겨진 파일이 나열되었습니다. 또한 해당 부분을 제외하면 -o -name "*"숨겨진 파일이 chmod된다는 사실도 확인했습니다(물론 숨겨지지 않은 파일은 제외됨). 내 마지막 시도는 대신 xargs를 사용하는 것이었습니다

find . -name ".*" -o -name "*" | xargs chmod go+w

마침내 예상대로 작동했습니다. 첫 번째 스니펫에서 내가 뭘 잘못하고 있는 걸까요?

Red Hat Enterprise Linux Server 릴리스 6.8(산티아고)

GNU bash, 버전 4.3.42(1)-릴리스(x86_64-unknown-linux-gnu)

답변1

해결책은 두 개의 이름 테스트를 괄호로 묶는 것입니다.

이를 설명하기 위해 세 개의 일반 파일이 있는 디렉토리를 고려해 보겠습니다.

$ ls -a
.  ..  .hidden1  .hidden2  not_hidden

이제 원래 명령을 살펴보겠습니다.

$ find . -name ".*" -o -name "*" -exec echo Found {} \;
Found ./not_hidden

숨겨지지 않은 파일만 발견됩니다.

다음으로 두 개의 이름 테스트를 함께 그룹화하기 위해 괄호를 추가해 보겠습니다.

$ find . \( -name ".*" -o -name "*" \) -exec echo Found {} \;
Found .
Found ./not_hidden
Found ./.hidden1
Found ./.hidden2

모든 파일이 발견되었습니다.

해결책은 괄호를 사용하는 것입니다.

자세한 내용은

-name "*"원래 명령에는 와 사이에 연산자가 없습니다 -exec ... \;. 결과적으로 find논리-and인 기본 연산자를 가정합니다. logic-and는 logic-or( -o)보다 더 긴밀하게 바인딩되므로 명령이 다음과 같이 해석됩니다.

find . \( -name ".*" \) -o \( -name "*" -exec echo Found {} \; \)

즉, exec첫 번째 name조건이 일치하지 않는 경우에만 실행됩니다.

자세한 내용은 다음을 참조하세요.연산자man find의 섹션

없이는 무슨 일이 일어나는가?-exec

간단한 것을 사용해 봅시다 -print:

$ find . -name ".*" -o -name "*" -print
./not_hidden

보시다시피, 위와 같이 암시적 logic-and를 사용하여 -printthe에 바인딩됩니다 .-name "*"

그러나 지정된 조치 없이 어떤 일이 발생하는지 생각해 보십시오.

$ find . -name ".*" -o -name "*"
.
./not_hidden
./.hidden1
./.hidden2

여기에서 모든 파일이 발견되었습니다. 그 이유는 이 버전 -o에서는오직운영자.

관련 정보