Perl:打开/关闭捕获返回码

时间:2015-02-24 15:16:40

标签: perl

myb.py

import time
import sys


stime = time.time()
run_until = 600

cnt = 0
while True:
    dur = time.time() - stime
    if dur > run_until:
        break

    cnt += 1
    print cnt
    time.sleep(1)

    if cnt == 10:
        sys.exit(2)            <---- capture 2

mya.pl

use FileHandle;

my $myexe = 'myb.py';
my $FH = FileHandle->new;
open $FH, q{-|},
    "$myexe 2>&1"
    or print "Cannot open\n";
process_output($FH);
close $FH or warn $!;

sub process_output {
    my ($fh) = @_;

    while (my $line = <$fh>) {
        chomp $line;
        print "$line\n";
    }

}

输出:

1
2
3
4
5
6
7
8
9
10
Warning: something's wrong at ./mya.pl line 10.

如果我将行更改为:

my $err = close $FH;

它给了我一个空白的错误。

问题:如何从mya.pl中的myb.py中捕获返回码2?

2 个答案:

答案 0 :(得分:5)

http://perldoc.perl.org/functions/close.html中所述,退出值作为$?的一部分提供。但是使用包装器会更方便:

use IPC::System::Simple qw(capture $EXITVAL EXIT_ANY);

my @output = capture([0,2], "$myexe 2>&1");
print @output;
print "Program exited with value $EXITVAL\n";

[0,2]表示退出值0或2是预期的,其他任何东西都是致命错误;您可以改用EXIT_ANY

这确实得到了最后的所有输出,而不是它产生的时候。

答案 1 :(得分:4)

open创建子女时,close的格式为waitpid,并相应地设置$?

$ perl -e'
   open(my $fh, "-|", @ARGV)
      or die $!;

   print while <$fh>;

   close($fh);
   if    ($? == -1 ) { die $!; }
   elsif ($? & 0x7F) { die "Killed by signal ".($? & 0x7F)."\n"; }
   elsif ($? >> 8  ) { die "Exited with error ".($? >> 8)."\n"; }
' perl -E'
   $| = 1;
   for (1..5) {
      say;
      sleep 1;
   }
   exit 2;
'
1
2
3
4
5
Exited with error 2