-> find .. -name bin -exec for file in {}/* ; do echo $file ; done \;
-bash: syntax error near unexpected token `do'
이 명령의 올바른 구문은 무엇입니까?
답변1
for
여러 문(예: -loop )을 인수로 사용하려면 명시적으로 셸을 호출 -exec
해야 합니다 bash
. 예:
find .. -name bin -exec bash -c 'for file in "$1"/* ; do echo "$file" ; done' none {} \;
공백이나 기타 적대적인 문자가 포함된 파일 이름에도 안전합니다.
bash -c
작동 원리
bash는 다음 형식의 명령을 사용하여 호출할 수 있습니다.
bash -c some_complex_commands arg0 arg1 arg2 ...
이 경우 bash는 string에 있는 모든 것을 실행합니다 some_complex_commands
. 이 명령은 일반 쉘을 사용하여 사용할 수 있습니다위치 매개변수. arg0
위 명령 뒤의 첫 번째 인수는 에 할당되고 $0
, 두 번째 인수는 에 할당되고 $1
, 세 번째 인수는 에 할당되는 $2
식입니다.
일반 셸 스크립트를 실행할 때 $0
이는 스크립트 이름과 $1
명령줄에 나타나는 첫 번째 인수입니다. 이 전통을 유지하면서 스크립트에 적절한 이름이 없기 때문에 파일 이름( find 표기법) bash -c
을 할당하도록 명령이 작성 되었습니다 . {}
$1
none
$0
답변2
원하는 것과 반대되는 결과를 얻고 있는 것 같습니다. 이 시도:
for f in `find .. -name bin`
do
echo $f
done
답변3
다음과 같이 기본 요소를 사용하여 의사 코드의 출력을 근사화할 수 있습니다 find
.
find .. -path \*/bin/\* ! -name .\*
...로 시작하지 않는 이름만 인쇄해야 합니다. 해당 이름은 어느 정도 상위 디렉터리에 뿌리를 두고 있으며, 더 큰 범위는 이라는 디렉터리에 뿌리를 두고 있습니다 /bin
.
일반적으로 하위 프로세스에서 루프를 실행하는 다양한 실제 목적을 생각할 수 있지만 find -exec
전달된 인수에 대해 shelld glob을 수행하는 것은 가능하지 않다고 생각합니다 find
. 의사코드와 동일한 작업을 수행하려면 printf
- 이를 사용하면 인수를 문자 그대로 출력으로 변환할 수 있으므로 다음과 같이 할 수 있습니다.
find .. -type d -name bin -exec sh -c '
printf %s\\n "$0/"*' {} \;
...루핑 없이 인쇄 및 와일드카드를 수행합니다 for
. 하지만 이 명령과 예제 명령의 한 가지 차이점은 이름과 일치하는 결과에 대한 사양과 유형이 없으면 -type d
결과는 d bin
가 된다는 것입니다 . 따라서 표준 출력에 기록되는 echo
많은 내용을 볼 가능성이 높습니다. bin/*
. 물론, 가 있더라도 해결 -type d
된다는 보장은 없습니다 *
. 빈 디렉터리나 .
파일만 포함된 디렉터리는 일치하는 항목을 렌더링하지 않으므로 이를 볼 수 있습니다.
{} \;
또한 이 예제는 다른 방법보다 훨씬 느릴 수 있는 기본 형식을 사용하므로 의사코드라는 점에 유의하세요 . printf
예를 들어 다음과 같이 작업을 다시 시도 합니다 .
find .. -type d -name bin -exec sh -c '
for d do printf %s\\n "$d/"*; done' -- {} +
...이것은 여전히 빈 glob 상황의 위험이 있지만 -exec
한 번에 하나의 쉘을 일치시키는 대신 실행 시 다른 프로세스에 합리적으로 전달할 수 있는 만큼의 인수를 수집하고 인수를 위치 매개변수 배열에 전달합니다. - 루프 sh
에서 "$@"
사용할 수 있습니다 for d do printf...
.
이제 단순히 결과를 인쇄하는 것(문장 내에서 반복할 때 일반적으로 유용하다고 생각하는 것) 이외의 다른 작업을 수행하려는 경우 이전 예제 -exec
로 돌아가서 다음과 같은 것과 결합할 수 있습니다.-path
-exec
find .. -path \*/bin/\* -exec sh -c '
for arg do : something with "$arg"
done' -- {} +