私の問題:findコマンドで返された結果が「最新」状態ではないようです。
私は次のようなbashスクリプトを持っています:
- ディレクトリからgifファイルのリストを取得します。
- pngを作成するには(imagemagickで)変換を使用します。
- 同じディレクトリにあるpngファイルのリストを取得します。 (ここにgifファイルがある場合は、以前に作成されたファイルが含まれている可能性があります。)
- optipngを使用して最適化します。
このスクリプトをそのままにしておくと、gifがあるとそのpngが見つかりません。キーボードで読んでスクリプトを強制的に一時停止すると、新しいpngが見つかります。
私の説明:
- 変換がすぐに返されるので、gifをpngファイルにする前にfind pngが実行されます。この場合、次のコマンドを強制的に待つ方法は何ですか?
- あるいは、 find コマンドは更新に時間がかかるシステム機能の一部を使用します。この場合、ディレクトリ情報を強制的に更新するにはどうすればよいですか?
ありがとう
答え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画像も探します。
新しく作成されたPNG画像でのみ実行するには、optipng
次を使用しますfind
。
find "$topdir" -type f -name '*.gif' -exec sh -c '
for gifpath do
pngpath=${gifpath%.gif}.png
convert "$gifpath" "$pngpath"
optipng "$pngpath"
done' sh {} +
または**
inを使用して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