Encontrar resultado não atualizado

Encontrar resultado não atualizado

Meu problema: os resultados retornados pelo comando find não parecem "atualizados".

Eu tenho um script bash no qual:

  1. eu recebo a lista de arquivos gif em um diretório
  2. eu uso convert (do imagemagick) neles para fazer png
  3. recebo a lista de arquivos png no mesmo diretório (que pode conter os gerados anteriormente se houvesse arquivos gif aqui)
  4. eu os otimizo com optpng

Se eu deixar esse script como está, quando tiver um gif, o png correspondente não será encontrado. Se eu forçar a pausa do script com uma leitura do teclado, o novo png será encontrado.

Minha interpretação:

  • ou a conversão retorna imediatamente, então find png é executado antes que o arquivo gif para png seja criado. Nesse caso, como forçar o próximo comando a esperar por ele?
  • ou o comando find usa algumas funções do sistema que precisam de tempo para serem atualizadas. Neste caso, como forçar a atualização em dir info ?

Obrigado

Responder1

Seguindo suas quatro etapas (ignorando as etapas "obter a lista...", pois elas não são necessárias):

#!/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 {} \;

Isso primeiro encontraria todos os arquivos regulares cujos nomes terminam em .gifou abaixo $topdire os converteria em imagens PNG.

Em seguida, ele encontra todas as imagens PNG da mesma maneira e executa optipngcada uma delas (observe que não sei nada sobre esse comando, então estou apenas supondo aqui). O segundo findtambém encontraria imagens PNG que possivelmente existiam antes da execução do script.

Se você deseja executar apenas optipngas imagens PNG recém-criadas, use um único find:

find "$topdir" -type f -name '*.gif' -exec sh -c '
    for gifpath do
        pngpath=${gifpath%.gif}.png
        convert "$gifpath" "$pngpath"
        optipng "$pngpath"
    done' sh {} +

Relacionado:Compreendendo a opção -exec de `find`

Ou, usando **in bashpara corresponder recursivamente em $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

Em cada trecho de código acima, o optipngcomando não seria executado até que o convertcomando fosse concluído. Se ainda assim isso causar problemas da mesma natureza que você descreveu (as imagens PNG não estão disponíveis depois convert), procurarei mensagens de erro que descrevam o que deu errado.

Responder2

Alguém recomendou um comando de sincronização, que faria com que o sistema liberasse todos os caches e evitasse negócios de disco inacabados.

Mas esse bug estranho desapareceu. Meu palpite: peculiaridade de sintaxe da minha parte, não detectada. No entanto, obrigado pela sua ajuda, e aqui está o que parece agora:

#!/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

informação relacionada