下面的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);
如何从各个命令获取退出状态值?
答案 0 :(得分:5)
要获取各个作业的存在状态,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文件将表明异常死亡。 (但你必须确保它首先不存在。)
答案 1 :(得分:3)
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
答案 2 :(得分: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"
答案 3 :(得分:0)
您可以使用CPAN提供的大量模块来提供类似的功能,而不是包装parallel
。
例如:
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);
}