find<의 -exec 부분에서 2 개의 명령을 사용할 수 있습니까? / div> 명령?

다음과 같은 것을 시도했습니다.

find . -name "*" -exec chgrp -v new_group {} ; chmod -v 770 {} \; 

다음을 얻습니다.

찾기 : -exec에 대한 인수 누락
chmod : 액세스 할 수 없음 {} : 해당 파일 또는 디렉토리 없음
chmod : 액세스 할 수 없음; : 해당 파일 또는 디렉토리 없음

댓글

  • -name "*"는 모든 이름과 일치합니다. 따라서 ' 제거 할 수있는 작동하지 않는 테스트입니다. 또한 chmodchgrp에는 재귀 연산을위한 -R 옵션이 있습니다.

Answer

find 명령의 경우 -exec 명령을 한 행에 더 추가 할 수도 있습니다.

find . -name "*" -exec chgrp -v new_group "{}" \; -exec chmod -v 770 "{}" \; 

이 명령은 t,

chgrp -v new_group 파일 & & chmod -v 770 파일

각 파일에.

-name, iv id = “a2d0ebcce4와 같은 모든 find“의 매개 변수 “>

, -size 등은 실제로 테스트 입니다. : find는 지금까지 전체 체인이 true 로 평가되는 한 하나씩 계속 실행합니다. 따라서 각 연속 -exec 명령은 이전 명령이 반환 된 경우에만 true (예 : 0 명령의 종료 상태). 그러나 find 또는 (-o)과 같은 논리 연산자도 이해하고 아닙니다 (!). 따라서 이전 결과의 에 관계없이 -exec 테스트 체인을 사용하려면 다음과 같은 것을 사용해야합니다.

find . -name "*" \( -exec chgrp -v new_group {} \; -o -true \) -exec chmod -v 770 {} \; 

댓글

  • +1 : 예, '가 가장 우아한 방법입니다. '{}' (중괄호 주위의 아포스트로피)를 사용하는 이유를 설명 할 수 있다면 다음을 방문하십시오. unix.stackexchange.com/q/ 8647/4485
  • @user 불행히도 ' 여전히 필요한지 모르겠습니다. 방금 몇 가지 테스트를했지만 ' 어떤 것도 변경 될 상황을 발견하지 못했습니다. '는 " 좋은 습관 " 일뿐입니다.

li>

  • 이름에 공백이있는 파일에는 따옴표가 중요합니다.
  • @ naught101 아니요, fishcsh,하지만 POSIX와 유사한 셸에는 반드시 필요하지 않습니다 (sh, dash, bash, zsh, ksh, yash).
  • 답변

    find . -name "*" -exec sh -c "chgrp -v new_group "$0" ; chmod -v 770 "$0"" {} \; 

    댓글

    • @Gilles : -c '의 이상한 취급의 경이로움 $ 0의 값은 매번 볼 때마다 이것이 틀렸다고 생각하게 만들지 만 확실히 맞습니다.
    • 명시적인 쉘이 정의되는 것을 좋아합니다 …
    • 이 답변 (그리고 Giles ' swer)가 sh -c를 고려할 때 더 나은 대답 인 것 같습니다.

    답변

    명령은 먼저 쉘에 의해 ;로 구분 된 두 개의 명령으로 구문 분석되며, 이는 줄 바꿈과 동일합니다.

    find . -name "*" -exec chgrp -v new_group {} chmod -v 770 {} \; 

    셸 명령을 실행하려면 bash -c (또는 sh -c를 사용하여 명시 적으로 셸이 특별히 bash인지는 신경 쓰지 않습니다.

    find . -name "*" -exec sh -c "chgrp -v new_group "$0"; chmod -v 770 "$0"" {} \; 

    {}를 쉘에 대한 인수; 이는 0 번째 인수 (일반적으로 쉘 또는 스크립트의 이름이지만 여기서는 중요하지 않음)이므로 "$0"로 참조됩니다.

    한 번에 여러 파일 이름을 셸에 전달하고 셸이 파일을 반복하도록 만들 수 있습니다. “더 빠를 것입니다. 여기서는 스크립트 이름으로 _를 전달하고 다음 인수는 다음과 같습니다. for x (for x in "$@"의 바로 가기)가 반복되는 파일 이름입니다.

    find . -name "*" -exec sh -c "for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done" _ {} + 

    bash 4 또는 zsh에서는 여기서 전혀 찾을 필요가 없습니다. bash에서는 (~/.bashrc에 입력)하여 재귀 디렉토리 glob을 나타내는 **/를 활성화합니다. (zsh에서는 항상 활성화됩니다.) 그런 다음

    chgrp -v new_group -- **/*; chmod -v 770 -- **/* 

    또는 파일을 순서대로 반복하려는 경우

    for x in **/*; do chgrp -v new_group -- "$x" chmod -v 770 -- "$x" done 

    find 명령과의 한 가지 차이점은 쉘이 도트 파일 (이름이 .로 시작하는 파일)을 무시한다는 것입니다. ).이를 포함하려면 bash에서 먼저 GLOBIGNORE=.:..를 설정하고 zsh에서는 **/*(D)를 glob 패턴으로 사용합니다.

    댓글

    • 이 답변 (및 Glenn '의 답변)은

    .

  • chgrpchmod 모두 -R 옵션
  • 답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다