3

シェル スクリプトの修正版は、オーディオ ファイルを FLAC から MP3 形式に変換します。コンピューターにはクアッドコア CPU が搭載されています。スクリプトは次を使用して実行されます。

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

これにより、ディレクトリ内の FLAC ファイル(ファイル名にスペースなし) がディレクトリ内 ( と同じレベル)flacの MP3 ファイルに変換されます。コピー先の MP3 ファイルが既に存在する場合、スクリプトはそのファイルをスキップします。mp3flac

問題は、スクリプトの 2 つのインスタンスが同じ MP3 ファイルの存在をほぼ同時にチェックすることがあり、その結果、MP3 ファイルが壊れることがあります。

コマンドラインごとに異なるファイルセットを指定したり、作業を上書きしたりせずに、スクリプトを複数回 (つまり、コアごとに 1 回) 実行するにはどうすればよいでしょうか?

更新 - 最小限の競合状態

このスクリプトは、次のロック メカニズムを使用します。

  # 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;

ただし、これでも競合状態が残ります。

4

8 に答える 8

6

「lockfile」コマンドは、競合状態のないシェル スクリプトに対して何をしようとしているかを提供します。このコマンドは、特にこの種の目的のために 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

あるいは、lockfile を無期限に再試行し続けるようにして、戻りコードをテストする必要がないようにすることもできます。代わりに、flac を実行するかどうかを判断するために出力ファイルをテストできます。

于 2009-09-25T02:57:32.693 に答える
1

出力を一意の名前で一時ファイルに送信し、ファイルの名前を目的の名前に変更します。

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

ファイル ロック システムから競合状態が時々発生する場合、最終的な出力は 1 つのプロセスの結果のままです。

于 2009-09-24T22:51:02.510 に答える
1

作業中の FLAC ファイルのロックを実装できます。何かのようなもの:

if (not flac locked)
  lock flac
  do work
else
  continue to next flac
于 2009-09-24T20:51:38.757 に答える
0

FLOM (Free Lock Manager)のようなツールを使用して、以下のようにコマンドを単純にシリアル化します。

flom -- flac ....
于 2014-04-03T20:58:55.347 に答える
0

ファイル プロセスをロックするには、.lock 拡張子が付いた同じ名前のファイルを作成します。

エンコーディングを開始する前に、.lock ファイルの存在を確認し、必要に応じてロックファイルの日付が古すぎないことを確認します (プロセスが終了した場合)。存在しない場合は、エンコードの開始前に作成し、エンコードの完了後に削除します。

ファイルを群れにすることもできますが、これは flock() を呼び出してファイルに書き込み、閉じてロックを解除する c でのみ機能します。シェル スクリプトの場合、ファイルの書き込みを行うために別のユーティリティを呼び出している可能性があります。

于 2009-09-24T21:03:24.123 に答える
0

Makefile を書いてみませんか?

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

それからする

$ make -j4 all
于 2009-09-24T21:19:03.803 に答える
0

bash では、ファイルの上書きを避けるために noclobber オプションを設定できます。

ヘルプセット | egrep 'noclobber|-C'

于 2009-09-24T21:51:52.223 に答える