Сценарий Bash для минимизации PNG продолжает останавливаться

Я попытался запустить этот скрипт несколько раз, и он продолжает висит. У меня 60 000 изображений, и он проходит около 1000, а затем останавливается. Я выполняю верхнюю команду, и процесс 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 

3 Solutions collect form web for “Сценарий Bash для минимизации PNG продолжает останавливаться”

Ответ Руи содержит некоторые полезные советы, хотя он, похоже, пропустил фактическую причину отказа вашей команды. Из вывода видно, что вы показываете, что у вас есть файл с именем ./12/thumbnail/The Official AndreasCY … . png ./12/thumbnail/The Official AndreasCY … . png .

Когда ты говоришь

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

это как сказать

  для PNG в ./12/thumbnail/112.png ./12/thumbnail/photography.png ./12/thumbnail/Christmas-01.png \
            ./12/thumbnail/OA1920.png ./12/thumbnail/ Официальный AndreasCY ....  png ... 

в результате, что ./12/thumbnail/The , Official и AndreasCY обрабатываются так, как если бы они были отдельными именами файлов, и, поскольку это не так, вы получаете полученную вами ошибку. Вы должны быть очень осторожны с использованием $(…) для создания списка имен файлов – под этим я подразумеваю, избегайте делать это, если это вообще возможно. find … -exec – гораздо лучший подход. Однако команда Rui не будет работать: -exec "Optimized PNG: " провалится, потому что нет такой команды, как "Optimized PNG: " .

Я предлагаю вам сохранить следующие части вашего первоначального ответа и ответ Руи:

  #! / Bin / ш

 cd / var / www / html / wp-content / uploads / 2014 (в конце концов вам не нужно «/»).
 найти .  -name '* .png' -type 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, – и я советую против этого.

В вашем сценарии выход поиска расширяется в фактическую командную строку, которая имеет ограничения по размеру. Итак, когда аргументы, полученные с помощью find, превышают размер, остальные игнорируются.

В этой статье рассматриваются проблемы: 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: " {} \; 

(\ используется для разрыва команды в двух строках, чтобы добавить ясность в сообщение)

Я также оставлю здесь статью об использовании find вместе с опцией exec.

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

Синтаксис Globbing можно поместить непосредственно в цикл for. Вам совсем не нужно find . И если вы используете globbing непосредственно в цикле 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-подобных системах, вы должны использовать один из других ответов.

  • Imagemagick используется для генерации PPM в Linux, PPM не читаются
  • Linux и Unix - лучшая ОС в мире.