0

我想在 Perl(命令行 PHP 脚本)中运行一个单独的进程。我想捕获这个过程的输出和返回代码。或者,如果该过程花费的时间超过 N 秒,我希望能够终止该过程并继续前进。我应该调查什么?

4

6 回答 6

2

你可以试试IPC::Run

IPC::Run - 带有管道、redirs、ptys(Unix、Win32)的系统()和后台进程

于 2012-11-26T20:37:13.600 回答
2

就个人而言,我发现最简单的是带有AnyEvent ::Util ::run_cmd 和计时器的 AnyEvent。这里不需要在事件循环下运行整个程序,我今天经常使用这个解决方案进出事件循环。(以下不是警告安全的。)

use AnyEvent;
use AnyEvent::Util;

my ($stdout, $stderr, $pid);

my $cv = AnyEvent::Util::run_cmd [ $^X, -e => '$|++; sleep 2; print "foo\n"; sleep 2' ],
    '>'  => \$stdout,
    '2>' => \$stderr,
    '$$' => \$pid,
;

my $w = AnyEvent->timer(after => 3, interval => 0, cb => sub { print "killing!\n"; kill SIGINT => $pid });

my $rc = $cv->recv();
$w = undef; # end the timer.

print "got rc = [$rc]\n";
print "stdout = [$stdout]\n";
print "stderr = [$stderr]\n";
于 2012-11-26T23:44:19.500 回答
1
use IPC::System::Simple qw/EXIT_ANY $EXITVAL capture/;

my $output = capture(EXIT_ANY, 'some command');
print "exit value was $EXITVAL\n";

EXIT_ANY告诉捕获允许任何退出值;您可以改为列出允许的 ( capture([0,1,42], ...)),如果遇到另一个异常,捕获将引发异常。默认情况下(如果只传递一个命令来捕获)任何非零退出值都会导致异常。

于 2012-11-26T21:08:07.647 回答
1

这是一个经常被问到的问题。也看看这个Perl FAQ。它基本上解释了在 Perl 中运行外部命令的方式。

于 2012-11-27T08:49:33.803 回答
1

您可以使用 piped open()来获得所有 3 个目标:

my $pid = open(F, "cat /etc/passwd |") || die "Cant open pipe: $!";
eval {
     # Give 30 secs to read output:
     local $SIG{ALRM} = sub { kill(9, $pid); die "alarm\n"; }; # NB: \n required
     alarm(30);

     # Read output:
     my $line = <F>;
     alarm(0); # Remove alarm

     #..do job with $line
};
# Get errorcode:
close(F);
print "Exit status: $?\n";
printf "Exit value(return code): %d\n", $?>>8;
print "Killed by timeout\n" if ($? & 127)==9;
于 2012-11-26T20:47:54.033 回答
0

在不考虑问题的可选部分的情况下,您可以在反引号中获取命令的输出,并在特殊变量中获取其返回值$?

my $output = `shell_command`;
die ("shell_command failed!\n") if ($?);
于 2021-03-03T10:25:17.393 回答