Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl IPC::不带out select的open3错误处理_Perl_Ipcopen3 - Fatal编程技术网

Perl IPC::不带out select的open3错误处理

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!

下面的代码运行良好,但我希望在不使用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! $!";

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。