并行运行Shell脚本循环

时间:2019-07-01 16:46:19

标签: linux bash shell unix

我写了一个shell脚本

  1. 从目录中获取所有图像文件的列表
  2. 根据需要创建新文件夹
  3. 优化图像以节省存储资源

我尝试在parallel -j "$(nproc)"之前使用mogrify,但发现这是错误的,因为在使用mogrify之前,使用DIR和mkdir,我需要在{的末尾添加&之类的东西。 {1}},但只能用于mogrify个进程。

当前代码如下:

n

有人可以建议并行运行此类脚本的正确方法是什么?每次运行大约需要15秒。

2 个答案:

答案 0 :(得分:0)

当您有一个进行某些设置并调用昂贵命令的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内核运行一个作业)。

答案 1 :(得分:0)

使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毫秒)。