Mi problema: los resultados devueltos por el comando de búsqueda no parecen "actualizados".
Tengo un script bash en el que:
- obtengo la lista de archivos gif en un directorio
- Utilizo convert (de imagemagick) en ellos para hacer png
- Obtengo la lista de archivos png en el mismo directorio (que pueden contener los generados anteriormente si hubiera archivos gif aquí)
- los optimizo con optipng
Si dejo este script como está, cuando tengo un gif, no se encuentra el png correspondiente. Si fuerzo la pausa del script con una lectura desde el teclado, entonces se encuentra el nuevo png.
Mi interpretación :
- O la conversión regresa inmediatamente, por lo que buscar png se ejecuta antes de que se cree el archivo gif a png. En este caso, ¿cómo forzar que el siguiente comando espere?
- o el comando de búsqueda utiliza algunas funciones del sistema que necesitan tiempo para actualizarse. En este caso, ¿cómo forzar la actualización de la información del directorio?
Gracias
Respuesta1
Siguiendo los cuatro pasos (ignorando los pasos de "obtener la lista..." ya que no son necesarios):
#!/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 {} \;
Esto primero buscaría todos los archivos normales cuyos nombres terminen en .gif
o debajo $topdir
y los convertiría a imágenes PNG.
Luego encuentra todas las imágenes PNG de la misma manera y las ejecuta optipng
en cada una (tenga en cuenta que no sé nada sobre este comando, así que solo estoy adivinando). El segundo find
también encontraría imágenes PNG que posiblemente existieran antes de ejecutar el script.
Si solo desea ejecutar optipng
en las imágenes PNG recién creadas, use un solo 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:Comprender la opción -exec de "buscar"
O usar **
in bash
para hacer coincidir recursivamente en $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
En todos y cada uno de los fragmentos de código anteriores, el optipng
comando no se ejecutaría hasta que convert
finalizara. Si aún así esto le genera problemas de la misma naturaleza que usted describe (las imágenes PNG no están disponibles después de convert
), entonces buscaría mensajes de error que describan lo que salió mal.
Respuesta2
Alguien recomendó un comando de sincronización, que habría hecho que el sistema vaciara todos los cachés y luego evitara problemas con el disco sin terminar.
Pero este extraño error desapareció. Mi conjetura: peculiaridad de sintaxis de mi parte, no detectada. De todos modos, gracias por tu ayuda y este es el aspecto que tiene ahora:
#!/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