capturing STDOUT from and piped "into" program

T

Tim

Hi

I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.

open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);

Can someone please show me an example on how I can directly place the
output of the above example into a scalar variable?


Up to now I've cludged it by placing the output into a file and then
reading it however it's ugly.

open(FULLSPEC,"|$p4 $spectype -i > $outfile");
print FULLSPEC @fullspec;
close(FULLSPEC);

open(OUTPUT,"<$outfile");
$specout = <OUTPUT>;
close(OUTPUT);
chomp($specout);
unlink($outfile);
return $specout;
 
P

Paul Lalli

Hi

I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.

open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);

Can someone please show me an example on how I can directly place the
output of the above example into a scalar variable?

Up to now I've cludged it by placing the output into a file and then
reading it however it's ugly.

open(FULLSPEC,"|$p4 $spectype -i > $outfile");
print FULLSPEC @fullspec;
close(FULLSPEC);

open(OUTPUT,"<$outfile");
$specout = <OUTPUT>;
close(OUTPUT);
chomp($specout);
unlink($outfile);
return $specout;

perldoc -q pipe
Found in /software/perl-5.8.5-0/pkg/lib/5.8.5/pod/perlfaq8.pod
How can I open a pipe both to and from a command?

http://perldoc.perl.org/IPC/Open2.html

[untested]
use IPC::Open2;
my $pid = open2(my $read_fh, my $write_fh, "$p4 $spectype -i");
print $write_fh @fullspec;
my $specout = do { local $/; <$read_fh> };

Hope this helps,
Paul Lalli
 
X

xhoster

Tim said:
Hi

I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.

open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);

One possibility, depending on what kinds of characters can exist in
@fullspec, would be:

my $output = `echo '@fullspec'|$p4 $spectype -i`;

For portability and also for safety (WRT weird characters in @fullspec) you
could use IPC::Open2, but you have to be careful to handle buffering to
avoid deadlock. Deadlock should not be a problem either if $p4 reads all
of the input before generating any output, or if join (" ", @fullspec) is
small. On many systems, small means less than 4096 bytes.

Perhaps a better answer would be IPC::Run:

my ($out,$err);
my $in=join " ", @fullspec;

IPC::Run::run([$p4, $spectype, '-i'],\$in,\$out,\$err) or die $!;

print $out;

Xho
 
T

Tim

Tim said:
I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.
open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);

One possibility, depending on what kinds of characters can exist in
@fullspec, would be:

my $output = `echo '@fullspec'|$p4 $spectype -i`;

For portability and also for safety (WRT weird characters in @fullspec) you
could use IPC::Open2, but you have to be careful to handle buffering to
avoid deadlock. Deadlock should not be a problem either if $p4 reads all
of the input before generating any output, or if join (" ", @fullspec) is
small. On many systems, small means less than 4096 bytes.

Perhaps a better answer would be IPC::Run:

my ($out,$err);
my $in=join " ", @fullspec;

IPC::Run::run([$p4, $spectype, '-i'],\$in,\$out,\$err) or die $!;

print $out;

Xho


Hi Paul and Xho

I really appreciate your responses. I initially tried Paul's solution.
It did indeed work on my OSX and Linux box. I was singing praises to
Paul but then I tried it on Windows XP with Activestate...
unfortunately it locked up.
I then went to try your solution.. It appears that IPC::Run is only
available in a separate package. I forgot to mention one detail ....
I'm attempting to write a perl benchmark test that customers could use
in their own perl environment without having them add additional
packages. :(

I'm using v5.8.5 on Linux and 5.8.8 Activestate on Windows. Knowing
what I just mentioned, any other ideas? Once again, thank you guys
VERY much for the info.

Tim
 
X

xhoster

Tim said:
Tim said:
I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.
open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);

One possibility, depending on what kinds of characters can exist in
@fullspec, would be:

my $output = `echo '@fullspec'|$p4 $spectype -i`;

For portability and also for safety (WRT weird characters in @fullspec)
you could use IPC::Open2, but you have to be careful to handle
buffering to avoid deadlock. Deadlock should not be a problem either
if $p4 reads all of the input before generating any output, or if join
(" ", @fullspec) is small. On many systems, small means less than 4096
bytes.

Perhaps a better answer would be IPC::Run:

my ($out,$err);
my $in=join " ", @fullspec;

IPC::Run::run([$p4, $spectype, '-i'],\$in,\$out,\$err) or die $!;

print $out;

Xho

Hi Paul and Xho

I really appreciate your responses. I initially tried Paul's solution.
It did indeed work on my OSX and Linux box. I was singing praises to
Paul but then I tried it on Windows XP with Activestate...
unfortunately it locked up.

How big was "@fullspec"? If it was big, then it maybe a buffering issue
that can solved with select. Even if it were not big, it still might be
one, but is likely.
I then went to try your solution.. It appears that IPC::Run is only
available in a separate package.

IPC::Run seems to be pure perl, and the source code is available, and thus
the source of it can be incorporated anywhere. I would assume its terms of
use would allow that, but I didn't check the license file--you should if
you want to use it that way. In any event, the ideas behind the package
are surely available to you.

Xho
 
T

Tim

I've read a lot good info on this list about capturing STDOUT but I'm
still having a problems grasping it. I think I'm missing something. I
am trying to capture the output from the "$p4 $spectype -i" command
and place it in a $scalar. I know I can't redirect directly into a
scalar.
open(FULLSPEC,"|$p4 $spectype -i");
print FULLSPEC @fullspec;
close(FULLSPEC);
Can someone please show me an example on how I can directly place the
output of the above example into a scalar variable?
Up to now I've cludged it by placing the output into a file and then
reading it however it's ugly.
open(FULLSPEC,"|$p4 $spectype -i > $outfile");
print FULLSPEC @fullspec;
close(FULLSPEC);
open(OUTPUT,"<$outfile");
$specout = <OUTPUT>;
close(OUTPUT);
chomp($specout);
unlink($outfile);
return $specout;

perldoc -q pipe
Found in /software/perl-5.8.5-0/pkg/lib/5.8.5/pod/perlfaq8.pod
How can I open a pipe both to and from a command?

http://perldoc.perl.org/IPC/Open2.html

[untested]
use IPC::Open2;
my $pid = open2(my $read_fh, my $write_fh, "$p4 $spectype -i");
print $write_fh @fullspec;
my $specout = do { local $/; <$read_fh> };

Hope this helps,
Paul Lalli


Hi Paul

I'm not sure whether you saw my respone. Thaniks for your input! - Tim

#####
Hi Paul and Xho

I really appreciate your responses. I initially tried Paul's solution.
It did indeed work on my OSX and Linux box. I was singing praises to
Paul but then I tried it on Windows XP with Activestate...
unfortunately it locked up.
I then went to try your solution.. It appears that IPC::Run is only
available in a separate package. I forgot to mention one detail ....
I'm attempting to write a perl benchmark test that customers could use
in their own perl environment without having them add additional
packages. :(

I'm using v5.8.5 on Linux and 5.8.8 Activestate on Windows. Knowing
what I just mentioned, any other ideas? Once again, thank you guys
VERY much for the info.

Tim
 
T

Tim

How big was "@fullspec"? If it was big, then it maybe a buffering issue
that can solved with select. Even if it were not big, it still might be
one, but is likely.


IPC::Run seems to be pure perl, and the source code is available, and thus
the source of it can be incorporated anywhere. I would assume its terms of
use would allow that, but I didn't check the license file--you should if
you want to use it that way. In any event, the ideas behind the package
are surely available to you.

Xho

Hi Xho

The input to @fullspec can vary. It can be VERY large (it is a source
control changelist for a branch). It can be 10,000 lines depending on
the dataset. The output is only one line.. the change number. Here is
a input file.

$ ls -l out
-rw-r--r-- 1 me me 133246 May 2 11:48 out

$ wc out
1454 4406 133246 out


dataset sample:

//depot/r45.0.0/0Jam/MAIN/src/RELNOTES # branch
//depot/r45.0.0/0Jam/MAIN/src/command.c # branch
//depot/r45.0.0/0Jam/MAIN/src/command.h # branch
//depot/r45.0.0/0Jam/MAIN/src/compile.c # branch
//depot/r45.0.0/0Jam/MAIN/src/compile.h # branch
//depot/r45.0.0/0Jam/MAIN/src/execcmd.h # branch

I'll look into IPC:Run a bit closer - Thx! Tim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top