私の問題: find コマンドによって返された結果が「最新」ではないようです。
以下の bash スクリプトがあります:
- ディレクトリ内のgifファイルのリストを取得します
- 私はこれらにconvert(imagemagickから)を使用してpngを作成します
- 同じディレクトリ内の png ファイルのリストを取得します (ここに gif ファイルがある場合は、以前に生成されたファイルも含まれる可能性があります)
- optipngで最適化します
このスクリプトをそのままにしておくと、gif がある場合、対応する png が見つかりません。キーボードからの読み取りでスクリプトを強制的に一時停止すると、新しい png が見つかります。
私の解釈:
- 変換がすぐに戻るので、gif から png へのファイルが作成される前に find png が実行されます。この場合、次のコマンドを強制的に待機させるにはどうすればよいでしょうか。
- または、find コマンドは更新に時間のかかるシステム関数を使用します。この場合、dir 情報を強制的に更新するにはどうすればよいでしょうか?
ありがとう
答え1
次の 4 つの手順に従います (「リストを取得...」の手順は不要なので無視します)。
#!/bin/bash
topdir=some/directory/path
find "$topdir" -type f -name '*.gif' -exec sh -c '
for gifpath do
convert "$gifpath" "${gifpath%.gif}.png"
done' sh {} +
find "$topdir" -type f -name '*.png' -exec optipng {} \;
.gif
これはまず、 内または 内で名前が終わるすべての通常ファイルを検索し$topdir
、それらを PNG 画像に変換します。
次に、同じ方法ですべての PNG 画像を検索し、optipng
それぞれに対して実行します (このコマンドについては何も知らないため、ここでは推測しているだけであることに注意してください)。2 番目は、find
スクリプトを実行する前に存在していた可能性のある PNG 画像も検索します。
optipng
新しく作成された PNG 画像のみを実行する場合は、 を 1 つ使用しますfind
。
find "$topdir" -type f -name '*.gif' -exec sh -c '
for gifpath do
pngpath=${gifpath%.gif}.png
convert "$gifpath" "$pngpath"
optipng "$pngpath"
done' sh {} +
関連している:`find` の -exec オプションを理解する
または、**
で を使ってbash
の下で再帰的に一致させます$topdir
。
#!/bin/bash
topdir=some/directory/path
shopt -s globstar nullglob dotglob
for gifpath in "$topdir"/**/*.gif; do
if [ -f "$gifpath" ]; then
pngpath=${gifpath%.gif}.png
convert "$gifpath" "$pngpath"
optipng "$pngpath"
fi
done
上記の各コードでは、コマンドが完了するoptipng
までコマンドは実行されませんconvert
。それでも、説明したのと同じ性質の問題 (PNG イメージが 以降に利用できないconvert
) が発生する場合は、何が問題だったかを説明するエラー メッセージを探してください。
答え2
誰かが sync コマンドを推奨しましたが、このコマンドはシステムにすべてのキャッシュをフラッシュさせ、未完了のディスク処理を回避させます。
しかし、この奇妙なバグは消えました。私の推測では、私の構文の癖が検出されなかったようです。それでも、ご協力ありがとうございました。現在の状況は次のようになります。
#!/bin/bash
clear
mapfile -t tab < <(jq -r '.[] | .' img_folders_to_optimize.json)
printf '%s\n' "${tab[@]}" | while read -r folder; do
echo "dossier à traiter : $folder"
cd "$folder" || exit
# GIF
for filepath in *.gif; do
echo "GIF : $filepath"
nb_frames=$(identify -format %n "$filepath")
if [ "$nb_frames" != 1 ]; then
echo "animated"
else
echo "convert to png"
filepath_png=${filepath/\.gif/.png}
convert "$filepath" "$filepath_png" &>/dev/null
echo "converted"
fi
done
# PNG
for filepath in *.png; do
echo "PNG : $filepath"
echo "optimize"
optipng -o7 -strip all "$filepath" &>/dev/null
echo "convert lossless to webp"
filepath_webp=${filepath/\.png/.webp}
cwebp -lossless "$filepath" -o "$filepath_webp" &>/dev/null
done
# JPG
for filepath in *.jpg; do
echo "JPG : $filepath"
echo "optimize"
mogrify -quality 70 "$filepath"
echo "convert lossy to webp"
filepath_webp=${filepath/\.jpg/.webp}
cwebp -q 50 -m 4 -mt "$filepath" -o "$filepath_webp"
done
echo "dossier traité"
done