7

以下のPerlラッパーはコマンドを並行して実行し、STDOUTとSTDERRを/tmpファイルに保存します。

open(A,"|parallel"); 
for $i ("date", "ls", "pwd", "factor 17") { 
  print A "$i 1> '/tmp/$i.out' 2> '/tmp/$i.err'\n"; 
} 
close(A); 

個々のコマンドから終了ステータス値を取得するにはどうすればよいですか?

4

4 に答える 4

7

個々のジョブの存在ステータスを取得するには、parallelどこかに情報を書き込む必要があります。そうかどうかはわかりません。そうでない場合は、自分でそれを行うことができます。

my %jobs = (
   "date"   => "date",
   "ls"     => "ls",
   "pwd"    => "pwd",
   "factor" => "factor 17",
);

open(my $parallel, "|parallel"); 
for my $id (keys(%jobs)) {
   print $parallel
      $jobs{$id}
      ." 1> '/tmp/$id.out'"
      ." 2> '/tmp/$id.err' ; "
      ."echo \$?"
      ." > '/tmp/$id.exit'\n"; 
} 

close($parallel); 

my $exit_status = $? >> 8;
if ($exit_status >= 255) {
    print("Failed\n");
} else {
    printf("%d failed jobs\n", $exit_status);
}

for my $id (keys(%jobs)) {
    ...grab output and exit code from files...
}

更新

行ってインストールしparallelました。

--joblog {file}終了コードを含むレポートを生成するというオプションがあります。-STDOUTに出力したい場合は、ファイル名を受け入れます。

信号による異常死を認識しないため、レポートparallelには含まれていません。--joblog上記で投稿したソリューションを使用すると、.exitファイルが見つからない場合は異常な死を示します。(ただし、そもそも存在しないことを確認する必要があります。)


更新

@Ole Tangeは、--joblog {file}上記の制限、つまり信号による死亡のログ記録の欠如がバージョン20110722で対処されていると述べています。

于 2011-06-10T19:27:45.723 に答える
6

GNU Parallel 20110722には、出口値とシグナルがあり--joblogます:

parallel --joblog /tmp/log false ::: a
cat /tmp/log
Seq     Host    Starttime       Runtime Send    Receive Exitval Signal  Command
1       :       1311332758      0       0       0       1       0       false a
于 2011-07-22T11:06:58.120 に答える
1

ラッパーを避けたい場合は、次のことを検討できます。

cat foo | parallel "{} >\$PARALLEL_SEQ.out 2>\$PARALLEL_SEQ.err; echo \$? >\$PARALLEL_SEQ.status"

バージョン20110422以降では、さらに短くなります。

cat foo | parallel "{} >{#}.out 2>{#}.err; echo \$? >{#}.status"

行に'が含まれていない場合は、これも機能するはずです。

cat foo | parallel "{} >'{}'.out 2>'{}'.err; echo \$? >'{}'.status"
于 2011-06-11T23:48:56.027 に答える
1

ラッピングの代わりにparallel、同様の機能を提供するCPANから入手可能な大量のモジュールのいずれかを使用できます。

例えば:

use Proc::Queue size => 10, qw(run_back);

my @pids;

for $i ("date", "ls", "pwd", "factor 17") {
  push @pids, run_back {
    open STDOUT, '>', '/tmp/$i.out';
    open STDERR, '>', '/tmp/$i.err';
    exec $i;
  }
}

for (@pids) {
  1 while waitfor($_, 0) <= 0;
  say "process $_ exit code: ", ($? >> 8);
}
于 2011-07-22T11:52:42.263 に答える