find
<의 -exec
부분에서 2 개의 명령을 사용할 수 있습니까? / div> 명령?
다음과 같은 것을 시도했습니다.
find . -name "*" -exec chgrp -v new_group {} ; chmod -v 770 {} \;
다음을 얻습니다.
찾기 : -exec에 대한 인수 누락
chmod : 액세스 할 수 없음 {} : 해당 파일 또는 디렉토리 없음
chmod : 액세스 할 수 없음; : 해당 파일 또는 디렉토리 없음
댓글
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>
fish
및 csh
,하지만 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 '의 답변)은
.
-
chgrp
및chmod
모두-R
옵션
-name "*"
는 모든 이름과 일치합니다. 따라서 ' 제거 할 수있는 작동하지 않는 테스트입니다. 또한chmod
및chgrp
에는 재귀 연산을위한-R
옵션이 있습니다.