exec에서 -if 명령 찾기

exec에서 -if 명령 찾기

나는 현재 디렉토리 아래의 모든 디렉토리와 파일을 나열하고 다음을 사용하여 파일인지 디렉토리인지 쓰고 싶습니다.

find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \;

나는 그것이 어리석은 명령이라는 것을 알고 있으며 -type f또는 같은 다른 명령을 사용할 수 있지만 -type d해당 코드 조각이 예상대로 작동하지 않는 이유를 이해하고 싶습니다. 단지 디렉토리를 모두 인쇄합니다. 예를 들어 출력은 다음과 같습니다 find.

.
./dir
./dir/file

내 코드의 출력은 다음과 같습니다

. : directory
./dir : directory
./dir/file : directory

그리고 출력

echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo directory;fi`

dir/file : file

연구 Ubuntu 14.10하고 사용하고 있어요find (GNU findutils) 4.4.2

답변1

먼저, 코드 조각이 명령을 실행합니다.

echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi

명령 대체를 평가하려면 출력이 필요하기 때문입니다. 라는 파일이 없으므로 {}출력이 생성됩니다.

{} :
directory

find그런 다음 명령은 -exec, echo, {}, 매개변수를 사용하여 실행되므로 각 파일에 대해 파일 이름 뒤에 공백 및 가 표시됩니다 .:directory: directory

echo {} :; …실제로 원하는 것은 에서 찾은 모든 파일에 대해 쉘 조각을 실행하는 것입니다 find. 이 코드 조각은 명령줄에서 데이터를 수신하므로 시작된 셸 find이 아닌 생성된 셸 에서 실행되어야 합니다 . 따라서 실행 중인 셸에 다음을 지시해야 합니다.findfindfind

find -exec sh -c 'echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi' \;

이것이 더 좋지만 여전히 옳지 않습니다. 파일 이름에 특수 문자가 포함되어 있지 않으면 일부(전부는 아님) 구현에서 작동 find하지만 쉘 스크립트에 파일 이름을 삽입하므로 파일 이름이 임의의 쉘 명령을 실행할 수 있도록 허용합니다. $(rm -rf /), 그러면 명령이 rm -rf /실행됩니다. 파일 이름을 스크립트에 전달하려면 별도의 인수로 전달하세요.

첫 번째는 echo콜론 뒤에 개행 문자를 인쇄합니다. 이를 피하려면 echo -n(쉘이 지원하는 경우) 또는를 사용하십시오 .printf

find -exec sh -c 'printf "%s :" "$0"; if [ -f "$0" ]; then echo file; else echo directory; fi' {} \;

-exec … {} +더 빠른 쉘 호출 그룹화를 사용할 수 있습니다 .

find -exec sh -c 'for x; do printf "%s :" "$x"; if [ -f "$x" ]; then echo file; else echo directory; fi; done' _ {} +

답변2

if; then; else; fi이를 수행하는 또 다른 방법은 다음과 같습니다 find.

find |
while IFS= read -r p; do if [ -f "$p" ]; then echo file; else echo directory; fi; done

관련 정보