Perl IPC::不带out select的open3错误处理
下面的代码运行良好,但我希望在不使用IO::Select的情况下实现同样的效果- 我尝试了一些东西,但没有任何效果,因为我对perl不太熟悉Perl IPC::不带out select的open3错误处理,perl,ipcopen3,Perl,Ipcopen3,下面的代码运行良好,但我希望在不使用IO::Select的情况下实现同样的效果- 我尝试了一些东西,但没有任何效果,因为我对perl不太熟悉 sub writeTologs { my $cmd=shift; open(ERRLOG, '>>log//error.log') or die "Can't open error log! $!"; open(OUTPUT, '>>log//output.log') or die "Can't open output log!
sub writeTologs
{
my $cmd=shift;
open(ERRLOG, '>>log//error.log') or die "Can't open error log! $!";
open(OUTPUT, '>>log//output.log') or die "Can't open output log! $!";
my ($infh,$outfh,$errfh); # these are the FHs for our child
$errfh = gensym(); # we create a symbol for the errfh # because open3 will not do that for us
my $pid;
#
eval{
$pid = open3($infh, $outfh, $errfh, $cmd);
};
die "open3: $@\n" if $@;
#
print "PID was $pid\n";
my $sel = new IO::Select; # create a select object to notify
# us on reads on our FHs (File Handlers)
$sel->add($outfh,$errfh); # add the FHs we're interested in
#
while(my @ready = $sel->can_read) { # read ready
foreach my $fh (@ready) {
my $line = <$fh>; # read one line from this fh
if(not defined $line){ # EOF on this FH
$sel->remove($fh); # remove it from the list
next; # and go handle the next FH
}
if($fh == $outfh) { # if we read from the outfh
print OUTPUT $line; # print it to OUTFH
}
elsif($fh == $errfh) {# do the same for errfh
print ERRLOG $line;
die "Error found : $@";
}
else { # we read from something else?!?!
die "Shouldn't be here\n";
}
}
}
close(ERRLOG) or die "Can't close filehandle! $!";
close(OUTPUT) or die "Can't close filehandle! $!";
}
我想在写入ERRLOG后终止我的进程
我试过以下代码-
open(ERRLOG, '>>log//error.log') or die "Can't open error log! $!";
open(OUTPUT, '>>log//output.log') or die "Can't open output log! $!";
my ($infh,$outfh,$errfh); # these are the FHs for our child
$errfh = gensym(); # we create a symbol for the errfh # because open3 will not do that for us
my $pid;
my $line=""; #
eval{
$pid=open3($infh, $outfh, $errfh, $cmd1);
};
die "open3: $@\n" if $@;
if (defined(<$errfh>)) {
print "Error start ".<$errfh>;
$errfh->close;
while($line = <$errfh>) {
print $line;
print "Inside while";
}
print "Error deifned \n";
} else {
while ($line=<$outfh>) {
print OUTPUT $line;
}
print "Output log";
}
但是,虽然循环没有在if条件内执行。我能够从下面的代码中实现这一点-
sub writeTologs {
my $cmd = shift;
my $strout = "$LOGDIR/$STDLOG";
my $strerr = "$LOGDIR/$ERRORLOG";
my $flag = 0;
my $line = '';
my $pid;
open(ERRLOG , '>>', $strerr ) or die "Can't open error log! $!";
open(SCHDLOG , '>>', $strout ) or die "Can't open output log! $!";
my ($infh,$outfh,$errfh);
$errfh = gensym();
eval
{
$pid = open3($infh, $outfh, $errfh, $cmd);
};
die "Open faile : $@" if $@;
my $line_err = <$errfh>;
if (defined(<$outfh>))
{
while($line = <$outfh>)
{
print SCHDLOG '[' . get_timestamp() . "]: $line";
}
}
if ($line_err)
{
print ERRLOG $line_err;
$flag =1 ;
}
print "PID = $pid";
waitpid($pid,0);
close(ERRLOG) or die "Can't close filehandle! $!";
close(SCHDLOG) or die "Can't close filehandle! $!";
return $flag;
}
请注意,通常情况下,如果不使用select或死锁风险,就无法同时读取stdout和stderr。是否有其他方法可以达到相同的结果,我正在检查IPC:Run。是的,您可以使用IPC::Run,如果可以使用open3和select完成,则可以使用更简单的IPC::Run3。