我想在Perl中运行一个单独的进程(命令行PHP脚本)。我想捕获这个进程输出和返回代码。我希望能够终止进程并继续进行,如果进程花费的时间超过N秒。我该怎么看?
答案 0 :(得分:2)
您可以尝试IPC::Run。
IPC :: Run - system()和后台进程/ piping,credits,ptys(Unix,Win32)
答案 1 :(得分: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], ...)
),如果遇到另一个,捕获将抛出异常。默认情况下(如果只传递一个命令来捕获),任何非零退出值都会导致异常。
答案 2 :(得分:1)
就个人而言,我发现最简单的是AnyEvent AnyEvent::Util :: run_cmd和一个计时器。这里没有要求在事件循环下运行整个程序,我今天经常使用此解决方案进出事件循环。 (以下不是警告 - 安全。)
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";
答案 3 :(得分:1)
这是一个经常被问到的问题。看看这个Perl FAQ也是如此。它基本上解释了在Perl中运行外部命令的方法。
答案 4 :(得分:0)
您可以使用管道打开()来实现所有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;
答案 5 :(得分:0)
在不考虑问题的可选部分的情况下,您可以在反引号内获取命令的输出,及其在特殊变量 $?
中的返回值。
my $output = `shell_command`;
die ("shell_command failed!\n") if ($?);