从 GNU 并行获取退出状态值

发布于 2024-11-14 19:30:12 字数 246 浏览 2 评论 0原文

下面的 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); 

如何从各个命令获取退出状态值?

The Perl wrapper below executes commands in parallel, saving STDOUT
and STDERR to /tmp files:

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

How do I obtain the exit status values from the individual commands?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如痴如狂 2024-11-21 19:30:12

要获取各个作业的存在状态,并行需要将信息写入某处。我不知道是不是这样。如果没有,您可以自己做。

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...
}

更新

我去安装了并行

它有一个名为 --joblog {file} 的选项,它会生成带有退出代码的报告。如果您希望它输出到 STDOUT,它接受 - 作为文件名。

请注意,parallel 无法通过信号识别异常死亡,因此这不包含在 --joblog 报告中。使用我上面发布的解决方案,丢失的 .exit 文件将表明异常死亡。 (不过,您必须首先确保它不存在。)


更新

@Ole Tange 提到我提到的 --joblog {file} 的限制上述问题已在版本 20110722 中得到解决。

To get the exist status of the individual jobs, parallel would need to write the info somewhere. I don't know if it does or not. If it doesn't, you can do that yourself.

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...
}

Update:

I went and installed parallel.

It has an option called --joblog {file} which produces a report with exit codes. It accepts - for file name if you want it to output to STDOUT.

Note that parallel doesn't recognise abnormal death by signal, so this is not included in the --joblog report. Using the solution I posted above, a missing .exit file would indicate an abnormal death. (You must make sure it doesn't exist in the first place, though.)


Update:

@Ole Tange mentions that the limitation of --joblog {file} I mentioned above, the lack of logging of death by signal, has been addressed in version 20110722.

清醇 2024-11-21 19:30:12

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

GNU Parallel 20110722 has exit val and signal in --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
小巷里的女流氓 2024-11-21 19:30:12

如果您想避免使用包装器,您可以考虑:

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"

If you want to avoid the wrapper you could consider:

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

Version 20110422 or later makes it even shorter:

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

If your lines do no contain ' then this should work too:

cat foo | parallel "{} >'{}'.out 2>'{}'.err; echo \$? >'{}'.status"
爱殇璃 2024-11-21 19:30:12

您可以使用 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);
}

Instead of wrapping parallel, you can use any of the tons of modules available from CPAN providing similar functionality.

For instance:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文