Найти результат неактуально

Найти результат неактуально

Моя проблема: результаты, возвращаемые командой find, кажутся «неактуальными».

У меня есть bash-скрипт, в котором:

  1. я получаю список gif-файлов в каталоге
  2. я использую convert (из imagemagick) для создания png
  3. я получаю список файлов png в том же каталоге (который может содержать ранее сгенерированные файлы, если здесь были файлы gif)
  4. я оптимизирую их с помощью optipng

Если я оставлю этот скрипт как есть, когда у меня есть gif, соответствующий png не будет найден. Если я заставлю скрипт остановиться с помощью чтения с клавиатуры, то будет найден новый png.

Моя интерпретация:

  • либо convert немедленно возвращается, поэтому find png выполняется до создания файла gif to 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 {} +

Связанный:Понимание опции -exec команды `find`

Или, используя **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

Связанный контент