同步shell脚本执行(Synchronize shell script execution)

2019-08-16 19:39发布

一个的修改版本shell脚本转换的音频文件从FLAC到MP3格式。 计算机有一个四核CPU。 该脚本运行使用:

./flac2mp3.sh $(find flac -type f)

这种转换在该FLAC文件flac目录(文件名无空格),在MP3文件mp3目录(在同一水平作为flac )。 如果目标MP3文件已经存在,脚本跳过该文件。

问题是,导致错位的MP3文件,在几乎相同的时间脚本检查为同一MP3文件的存在,有时两个实例。

你会如何运行脚本多次(即,每一次核心),而不必指定不同的文件在每个命令行设置,并且不覆盖的工作?

更新-最小竞争条件

该脚本使用下面的锁定机制:

  # Convert FLAC to MP3 using tags from flac file.
  #
  if [ ! -e $FLAC.lock ]; then
    touch $FLAC.lock
    flac -dc "$FLAC" | lame${lame_opts} \
      --tt "$TITLE" \
      --tn "$TRACKNUMBER" \
      --tg "$GENRE" \
      --ty "$DATE" \
      --ta "$ARTIST" \
      --tl "$ALBUM" \
      --add-id3v2 \
      - "$MP3"
    rm $FLAC.lock
  fi;

然而,这仍然留下了竞争条件。

Answer 1:

该“锁定文件”命令提供你想要的shell脚本做没有竞争条件是什么。 该命令是专门为这种目的的写入由procmail的人,是可以在大多数BSD / Linux系统(如procmail的可用于大多数环境)。

您的测试变得像这样:

lockfile -r 3 $FLAC.lock
if test $? -eq 0 ; then
  flac -dc "$FLAC" | lame${lame_opts} \
    --tt "$TITLE" \
    --tn "$TRACKNUMBER" \
    --tg "$GENRE" \
    --ty "$DATE" \
    --ta "$ARTIST" \
    --tl "$ALBUM" \
    --add-id3v2 \
    - "$MP3"
fi
rm -f $FLAC.lock

或者,你可以把锁文件不断重试下去,所以你不需要测试返回码,而是可以测试输出文件以确定是否运行后手。



Answer 2:

如果你没有lockfile ,不能安装它(在任何版本的-有几个实现)一个强大的和便携式原子互斥mkdir

如果你尝试创建目录已经存在, mkdir会失败,所以你可以检查是什么; 当创建成功,你必须保证没有其他的合作过程是在同一时间,你的代码的关键部分。

if mkdir "$FLAC.lockdir"; then
    # you now have the exclusive lock
    : critical section
    : code goes here
    rmdir "$FLAC.lockdir"
else
    : nothing? to skip this file
    # or maybe sleep 1 and loop back and try again
fi

为了完整起见,也许也寻找flock ,如果你是一组,其中被可靠地提供平台,需要一个高性能的替代lockfile



Answer 3:

你可以实现的,它的工作FLAC文件锁定。 就像是:

if (not flac locked)
  lock flac
  do work
else
  continue to next flac


Answer 4:

输出发送到一个独特的名字的临时文件,然后重命名该文件为所需的名称。

flac -dc "$FLAC" | lame${lame_opts} \
      --tt "$TITLE" \
      --tn "$TRACKNUMBER" \
      --tg "$GENRE" \
      --ty "$DATE" \
      --ta "$ARTIST" \
      --tl "$ALBUM" \
      --add-id3v2 \
      - "$MP3.$$"
mv "$MP3.$$" "$MP3"

如果通过你的文件中的竞争状态泄漏的同时,锁定系统每一次,最终的输出仍然会一个过程的结果。



Answer 5:

锁定文件过程中,你可以创建一个.lock扩展名的同名文件。

在开始之前编码检查.lock文件是否存在,以及可选确保锁定文件的日期是不是太旧(如果该进程死亡)。 如果它不存在,创建它的编码开始之前,编码完成后删除它。

您也可以蜂拥而至的文件,但这个只有真正的作品在C你在哪里调用flock()和写入文件,然后关闭和解锁。 对于一个shell脚本,你可能被调用另一个实用程序执行文件的写入。



Answer 6:

如何写一个Makefile?

ALL_FLAC=$(wildcard *.flac)
ALL_MP3=$(patsubst %.flac, %.mp3, $(ALL_FLAC)
all: $(ALL_MP3)
%.mp3: %.flac
        $(FLAC) ...

然后做

$ make -j4 all


Answer 7:

在bash它可以设置noclobber选项,以避免文件覆盖。

帮助设置| egrep的 'noclobber选项| -C'



Answer 8:

使用类似的工具富勒姆(无锁管理器)和简单的序列化你的命令,如下:

flom -- flac ....


文章来源: Synchronize shell script execution