Perl - "tee" qx statement

I am working on a script that currently has:

my @files = `$some_command`;
print @files;
chomp @files;
foreach my $file (@files)
{
    process($file);
}

It works correctly, but the part some_commandtakes most of the time script. And during this time nothing appears on stdout, because Perl redirected the output from some_commandto fill the array @files. It is printed only when it some_commandis executed, and Perl switches to print @files;.

Is there any smart way to change this code so that the result some_commandappears as it executes? I could try something like this using tee(1):

my $tmpfile = File::Temp->new();
system("$some_command | tee " . $tmpfile->filename);
my @files;
{ local $/ = undef; @files = split /\s/, <$tmpfile>; }

But I would prefer to avoid a temporary file if there is a simpler solution.

+3
source share
5 answers

.

, - ,

  open my $fh, '-|', $some_command;
  while(<$fh>)
  {
    print $_;
    push @files, $_;
  }
  close $fh;
+5

qx() . my @files = qx($some_command):

 my @files = ();
 open my $proc_fh, "$some_command |";
 while (<$proc_fh>) {
     push @files, $_;
 }
 close $proc_fh;

while , , $_:

 while (<$proc_fh>) {
     print "INPUT: $_\n";
     push @files, $_;
 }

$some_command. , $proc_fh , .

+2

File::Tee , , . STDOUT system(). , , , .

+1

You can also open your command as a file descriptor and read the result as it is created. Something like this (taken from http://www.netadmintools.com/art269.html ):

#!/usr/bin/perl
open (PINGTEST, "/bin/ping  -c 5 netadmintools.com |");
$i=1;
while (<PINGTEST>){
print "Line # ".$i." ".$_;
$i++;
}
print "All done!\n";
close PINGTEST;
+1
source

Capture :: Tiny is probably exactly what you want.

   use Capture::Tiny qw/ tee tee_merged /;

   ($stdout, $stderr) = tee {
     # your code here
   };

   $merged = tee_merged {
     # your code here
   };
+1
source

Source: https://habr.com/ru/post/1792861/


All Articles