尋找結果不是最新的

尋找結果不是最新的

我的問題: find 命令返回的結果似乎不是「最新的」。

我有一個 bash 腳本,其中:

  1. 我得到目錄中的 gif 檔案列表
  2. 我在它們上使用convert(來自imagemagick)來製作png
  3. 我得到同一目錄中的 png 文件列表(如果這裡有 gif 文件,則可能包含先前生成的文件)
  4. 我用 optipng 優化它們

如果我按原樣保留此腳本,當我有 gif 時,找不到相應的 png。如果我透過鍵盤讀取強制腳本暫停,則會找到新的 png。

我的解釋:

  • 要么轉換立即返回,所以 find png 在創建 gif 到 png 檔案之前執行。在這種情況下,如何強制等待下一個指令呢?
  • 或者find指令使用了一些需要時間更新的系統功能。在這種情況下,如何強制更新目錄資訊?

謝謝

答案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 {} \;

這將首先找到名稱以.gifin 或 under結尾的所有常規文件$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 {} +

有關的:了解“find”的 -exec 選項

或者,使用**inbash在 下遞歸匹配$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命令,這會讓系統刷新所有緩存,然後避免未完成的磁碟業務。

但這奇怪的bug卻消失了。我的猜測:我的語法怪癖,沒有檢測到。儘管如此,還是感謝您的幫助,現在的情況如下:

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

相關內容