以下の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);
個々のコマンドから終了ステータス値を取得するにはどうすればよいですか?
以下の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);
個々のコマンドから終了ステータス値を取得するにはどうすればよいですか?
個々のジョブの存在ステータスを取得するには、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で対処されていると述べています。
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
ラッパーを避けたい場合は、次のことを検討できます。
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"
ラッピングの代わりに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);
}