PNG 축소를 위한 Bash 스크립트가 계속 중지됩니다.

PNG 축소를 위한 Bash 스크립트가 계속 중지됩니다.

이 스크립트를 몇 번 실행해 보았지만 계속 중단됩니다. 60,000개의 이미지가 있는데 약 1000개의 이미지 후에 중지됩니다. top 명령을 계속 실행했는데 pngQuant 프로세스가 사라지는 것 같습니다. 어떤 도움이라도 대단히 감사하겠습니다.

내가 얻는 마지막 결과는 다음과 같습니다.

Optimized PNG: ./12/thumbnail/112.png
Optimized PNG: ./12/thumbnail/photography.png
Optimized PNG: ./12/thumbnail/Christmas-01.png
Optimized PNG: ./12/thumbnail/OA1920.png
error: cannot open ./12/thumbnail/The for reading
Optimized PNG: ./12/thumbnail/The
error: cannot open Official for reading
Optimized PNG: Official
error: cannot open AndreasCY for reading
Optimized PNG: AndreasCY

그런 다음 멈췄습니다. 스크립트는 다음과 같습니다.

#!/bin/bash

cd /var/www/html/wp-content/uploads/2014/

for PNG in $(find . -name '*.png'); do

  pngquant --ext .png --force 256 ${PNG}
  echo "Optimized PNG: ${PNG}"

done

답변1

Rui의 답변에는 몇 가지 좋은 조언이 포함되어 있지만 명령이 실패하는 실제 이유를 놓친 것 같습니다. 출력에서 볼 수 있듯이 ../12/thumbnail/The Official AndreasCY ….png

네가 말할 때

for PNG in $(find . -name '*.png')

그것은 마치 말하는 것과 같다

./12/thumbnail/112.png ./12/thumbnail/photography.png ./12/thumbnail/Christmas-01.png \에 사용 가능
           ./12/thumbnail/OA1920.png ./12/thumbnail/OfficialAndreasCY…..png...

결과적으로 ./12/thumbnail/The, Official, 및 는 AndreasCY 별도의 파일 이름으로 처리되며 별도의 파일 이름이 아니므로 오류가 발생합니다. 파일 이름 목록을 생성하기 위해 이것을 사용할 때는 매우 주의해야 합니다 $(…). 즉, 가능하면 사용하지 않는 것이 좋습니다.  find … -exec더 나은 방법입니다. 그러나 Rui가 제공한 명령은 작동하지 않습니다. -exec "Optimized PNG: " 해당 명령이 없기 때문에 실패합니다 "Optimized PNG: ".

원래 답변과 Rui 답변의 다음 부분을 유지하는 것이 좋습니다.

#!/bin/sh

CD /var/www/html/wp-content/uploads/2014        (실제로 후행 "/"는 필요하지 않습니다.)
찾다. -이름 '*.png' -유형 f ...

그런 다음 다음 작업 중 하나를 사용하여 완료합니다.

  • -exec pngquant --ext .png --force 256 {} \; -exec echo "Optimized PNG:" {} \;
  • -exec pngquant --ext .png --force 256 {} \; -printf "Optimized PNG: %p\n"
  • -exec sh -c 'pngquant --ext .png --force 256 "$1"; echo "Optimized PNG: $1"' sh {} \;, 또는
  • -exec myscript {} \;
    myscript어디

    #!/bin/sh
    pngquant --ext .png --force 256 "$1"
    echo "Optimized PNG: $1"
    

타당한 이유가 없는 한 항상 쉘 변수(예: "$PNG"및 )를 인용해야 합니다."$1"틀림없이당신은 당신이 무엇을하고 있는지 알고 있습니다. 대조적으로 중괄호(예: ${PNG})는 중요할 수 있지만 따옴표만큼 중요하지는 않습니다. 그리고 일반적으로 #!/bin/sh bash 기능에 의존하고 POSIX 호환 셸과 함께 사용할 수 없는 스크립트를 명시적으로 작성하지 않는 한 이를 권장합니다.

답변2

스크립트에서 찾기 출력은 크기가 제한된 실제 명령줄로 확장됩니다. 따라서 find에 size보다 많은 인수가 제공되면 나머지는 무시됩니다.

이 문서에서는 문제가 있는 부분을 다룹니다. http://www.cyberciti.biz/faq/argument-list-too-long-error-solution/

find 명령은 또한 매우 강력한 명령이며 명령을 호출하는 옵션이 있습니다. 이는 대용량 파일 작업 시 이러한 제한을 없애는 방법 중 하나입니다.

다음과 같이 명령을 실행할 수 있습니다.

find $DIR -name '*.png' -type f -exec command {} \;

여기서 {}는 처리 중인 파일이고, 유형 f는 처리 중인 파일을 정의하며, $DIR은 명령이 재귀적으로 작동하는 기본 디렉터리입니다.

생산 라인에서 원하는 것을 달성하는 간단한 방법은 다음과 같습니다.

find /var/www/html/wp-content/uploads/2014 . -name '*.png' -type f \ 
-exec pngquant --ext .png --force 256 {} \; -exec echo "Optimized PNG: " {} \;

(\는 게시물의 명확성을 높이기 위해 명령을 두 줄로 나누는 데 사용됩니다)

또한 exec 옵션과 함께 find를 사용하는 방법에 대한 기사를 여기에 남길 것입니다.

http://linuxaria.com/howto/linux-shell-how-to-use-the-exec-option-in-find-with-examples

답변3

Globbing 구문은 for 루프에 직접 넣을 수 있습니다. find전혀 그럴 필요가 없습니다 . for 루프에서 직접 와일드카드를 사용하는 경우 쉘이 이를 자동으로 처리하므로 단어 분리에 대해 걱정할 필요가 없습니다.

쉘 변수가 명령에 나타날 때 이를 인용하는 것도 좋은 생각입니다. 그렇지 않으면 대체 후 토큰화됩니다.

결국 파일 이름에 특정 문자가 포함되어 있으면 더 정확하게 작동하고 다른 구현 간에 더 이식성이 높기 때문에 printf대신 선호하십시오.echo

for PNG in *.png; do

  pngquant --ext .png --force 256 "$PNG"
  printf "Optimized PNG: %s\n" "$PNG"

done

zsh와 bash에서및 관련 옵션 세트, 다음과 같이 재귀적 글로브를 수행할 수 있습니다.

for PNG in **/*.png; do

  pngquant --ext .png --force 256 "$PNG"
  printf "Optimized PNG: %s\n" "$PNG"

done

find그러면 명령 과 마찬가지로 검색이 하위 디렉터리로 이동하게 됩니다 . 그러나 이는 POSIX 표준이 아니므로 모든 POSIX 유사 시스템에서 이식 가능하게 작업해야 하는 경우 다른 답변 중 하나를 사용해야 합니다.

관련 정보