並列コマンドが「起動中」と「完了」の両方を印刷するのはなぜですか?

並列コマンドが「起動中」と「完了」の両方を印刷するのはなぜですか?
ls *.txt | parallel 'echo Starting on file {}; mkdir {.}; cd {.}; longCMD3 ../{} > /dev/null; echo Finished file {}'

このライナーは部分的に機能します。ただし、longCMD3は約3分かかりますが、最初と2番目のechoコマンドはほぼ同時に印刷されます。入れてみました

wait

Last Echo 以前ですが、違いはありません。

longCMD3が完了した後にのみ最終エコーが印刷されるようにするにはどうすればよいですか?

これは例です

コアが4つしかないとしましょう。

ls
foo1.txt foo2.txt foo3.txt foo4.txt foo5.txt foo6.txt 

私が期待したもの:

Starting on file foo1.txt
Starting on file foo2.txt
Starting on file foo3.txt
Starting on file foo4.txt

これにより、longCMD3がファイルの1つを完了するのに少なくとも2分かかります。

Finished file foo1.txt
Starting on file foo5.txt

しかし、私が得るものは次のとおりです。

Starting on file foo1.txt
Finished file foo1.txt
Starting on file foo2.txt
Finished file foo2.txt
Starting on file foo3.txt
Finished file foo3.txt
Starting on file foo4.txt
Finished file foo4.txt

これは6つのファイルすべてに当てはまります。各ファイルの開始文と完了文が同時に印刷されます。ただし、各ファイル間には数分かかります。

ベストアンサー1

echo Starting on file foo.txt各ファイルに対して、mkdir fooおよびコマンドはcd foo順次実行されます。つまり、各コマンドは、前のlongCMD3 ../foo.txt > /dev/nullコマンドがecho Finished file foo.txt完了した後に開始されます。

さまざまなファイルのコマンドが散在しています。デフォルトでは、並列コマンドはコア数と同じ数のジョブを並列に実行します。

しかし、出力デフォルトでは、コマンドは拡散されません。これが、複数の「開始」行が表示されず、それに対応する「完了」行が表示されない理由です。各ジョブの出力を並列にグループ化します。ジョブが完了するまで出力をバッファリングします。--groupこのオプションの説明については、マニュアルを参照してください。あなたの場合はグループ化が適していないので、--ungroup-u)オプションを使用してオフにするか、を使用して行グループ化に切り替えます--line-buffer

その他の修正:

  • ls 構文解析は信頼できません。。ファイル名を直接渡しますparallel
  • mkdir失敗した場合は続行しないでください。コマンドが失敗した場合は、ジョブが失敗するようにスケジュールする必要があります。簡単な方法は、作業スクリプトを起動することです。set -e
parallel --line-buffer 'set -e; echo Starting on file {}; mkdir {.}; cd {.}; longCMD3 ../{} > /dev/null; echo Finished file {}' ::: *.txt

おすすめ記事