내 문제: find 명령으로 반환된 결과가 "최신"인 것 같지 않습니다.
다음과 같은 bash 스크립트가 있습니다.
- 나는 디렉토리에 있는 gif 파일 목록을 얻습니다
- 나는 png를 만들기 위해 (imagemagick에서) 변환을 사용합니다.
- 동일한 디렉토리에 있는 png 파일 목록을 얻습니다(여기에 gif 파일이 있는 경우 이전에 생성된 파일이 포함될 수 있음).
- 난 optipng로 최적화해
이 스크립트를 그대로 두면 gif가 있을 때 해당 png를 찾을 수 없습니다. 키보드에서 읽은 후 스크립트를 강제로 일시 중지하면 새 png가 발견됩니다.
내 해석 :
- 변환이 즉시 반환되므로 gif to png 파일이 생성되기 전에 png 찾기가 실행됩니다. 이 경우 다음 명령을 강제로 기다리게 하는 방법은 무엇입니까?
- 또는 find 명령은 업데이트하는 데 시간이 필요한 일부 시스템 기능을 사용합니다. 이 경우 dir info를 강제로 업데이트하는 방법은 무엇입니까?
감사해요
답변1
네 가지 단계를 따르십시오("목록 가져오기..." 단계는 필요하지 않으므로 무시).
#!/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
각 이미지에서 실행합니다(저는 이 명령에 대해 아무것도 모르므로 여기서는 추측일 뿐입니다). 두 번째는 find
스크립트를 실행하기 전에 존재했을 가능성이 있는 PNG 이미지도 찾습니다.
optipng
새로 생성된 PNG 이미지에서만 실행하려면 다음을 사용하세요 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
누군가 시스템이 모든 캐시를 플러시하고 완료되지 않은 디스크 작업을 방지하도록 하는 동기화 명령을 권장했습니다.
그런데 이 이상한 버그가 사라졌습니다. 내 추측으로는 내 부분의 구문 문제가 발견되지 않았습니다. 그럼에도 불구하고 도움을 주셔서 감사합니다. 현재 상황은 다음과 같습니다.
#!/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