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 コマンドも非常に強力なコマンドであり、コマンドを呼び出すオプションがあります。これは、大容量ファイルを操作するときにこれらの制限を取り除く方法の1つです。

次のようにコマンドを実行できます。

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: " {} \;

(\はポストの明確さを高めるためにコマンドを2行に分割するために使用されます)

また、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様システムで移植可能に作業する必要がある場合は、他の答えの1つを使用する必要があります。

関連情報