簡體   English   中英

並行運行Shell腳本循環

[英]Running shell script loop in parallel

我寫了一個shell腳本

  1. 從目錄獲取所有圖像文件的列表
  2. 如果需要新圖像,請創建新文件夾
  3. 優化映像以節省存儲資源

我試着在mogrify之前使用parallel -j "$(nproc)" ,但是發現這是錯誤的,因為在使用mogrify之前,使用DIR和mkdir,我需要在mogrify末尾添加& ,但是只對n做流程。

當前代碼如下:

#!/bin/bash

find $1 -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -type f | while read IMAGE
do
    DIR="$2"/`dirname $IMAGE`
    echo "$IMAGE > $DIR"
    mkdir -p $DIR
    mogrify -path "$DIR" -resize "6000000@>" -filter Triangle -define filter:support=2 -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB "$IMAGE"
done

exit 0

有人可以建議並行運行此類腳本的正確方法是什么? 因為每次運行大約需要15秒。

當您有一個執行某些設置並調用昂貴命令的shell循環時,對其進行並行化的方法是使用來自GNU parallel的sem

for i in {1..10}
do
  echo "Doing some stuff"
  sem -j +0 sleep 2
done
sem --wait

這樣可以使循環正常運行並執行其操作,同時還可以調度命令以並行運行( -j +0每個CPU內核運行一個作業)。

創建一個bash函數以正確處理一個文件並並行調用:

#!/bin/bash

doit() {
  IMAGE="$1"
  DIR="$2"/`dirname $IMAGE`
  echo "$IMAGE > $DIR"
  mkdir -p $DIR
  mogrify -path "$DIR" -resize "6000000@>" -filter Triangle -define filter:support=2 -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -define png:exclude-chunk=all -interlace none -colorspace sRGB "$IMAGE"
}
export -f doit

find $1 -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -type f |
    parallel doit

GNU Parallel的默認設置是每個CPU線程運行一個作業,因此ǹproc

這比每個文件開始sem開銷要少(每個呼叫sem = 0.2秒, parallel = 7 ms /呼叫)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM