찾기: 중첩된 명령에서 현재 파일 이름이 NULL로 평가됩니다.

찾기: 중첩된 명령에서 현재 파일 이름이 NULL로 평가됩니다.

크기에 따라 디렉토리에 있는 이미지 세트의 이름을 바꾸려고 합니다. 이를 위해 Imagemagik의 명령을 사용하여 단계별로 명령을 작성하고 있습니다 identify. 현재 사용 중인데 출력이 정확해지면 전환 echo할 계획입니다 .mvecho

find * -type f -exec echo "$(identify -format '%w-%h' {})" \;

그러면 빈 줄이 많이 출력됩니다. 하지만 에코 없이 직접 실행해 보면,

find * -type f -exec identify -format '%w-%h' {} \;

예상대로 크기가 출력됩니다. 내부 명령이 정상적으로 실행되지 않는 이유는 무엇입니까?

답변1

확장하려면 내부에 무엇이 들어 있는지 echo모르기 때문입니다 . 이 경우 모드 에서 사용해야 한다는 점만 이해하세요 .{}exec{}sh -c

find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '{}' \;

답변2

사용:

find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;

설명하다

문제는 bash가 변수를 확장하는 방식에 있습니다.

find * -type f -exec echo "$(identify -format '%w-%h' {})" \;

먼저 bash는 side의 콘텐츠를 확장합니다 $(...).

find * -type f -exec echo 'identify: unable to open image `{}': No such file or directory...' \;

이 시점에서 find는 상당히 쓸모없는 인수가 있는 모든 명령에 대해 동일한 exec 문을 사용합니다. 당신이 원하는 것은 exec 내부에 있는 bash 확장을 억제하는 것입니다. 콘텐츠를 작은따옴표로 묶어서 bash가 콘텐츠를 확장하는 것을 방지할 수 있습니다.

find * -type f -exec echo '$(identify -format %w-%h {})' \;

하지만 여기서는 확장이 완전히 사라졌습니다. 다음 표현식을 실행하여 다시 주입할 수 있습니다.sh -c

find * -type f -exec sh -c 'echo "$(identify -format %w-%h {})"' \;

{}이를 쉘 스크립트에 배치하면 파일 이름의 공백, 따옴표 또는 쉘 특수 문자를 처리할 때 예상치 못한 오류가 발생할 수도 있습니다. 이 문제를 해결하려면 {}as 매개변수를 sh로 이동해야 합니다.

find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;

자세한 설명은 이 질문/답변을 참조하세요.

마지막으로, 로 대체하여 현재 디렉터리에서 자체적으로 파일을 찾도록 할 수 있습니다 *( 숨겨진 파일을 포함하고 로 시작하는 파일 이름에 대해 실패하지 않음 .) .find-

또한 명령 디버깅을 돕기 위해 실행된 내용을 인쇄하도록 -x플래그를 추가할 수 있습니다. 이는 많은 파일에서 매우 시끄러울 수 있습니다.sh

관련 정보