Solved

Using Perl open with pipes

Posted on 1997-08-30
4
469 Views
Last Modified: 2008-03-04
I have a question regarding the 'piping' of output
via an 'open' command.  Essentially I am invoking a
database connection using the database's proprietary command line
utility and I will be passing SQL commands through
the file handle.  My problem lies in effeciently capturing
to database output into a buffer or filehandle.  Presently
I am 'piping' the output to another perl script which
uses 'while (<>)' to process the stream and load a buffer.
However I want to avoid invoking another perl script and
would rather load a buffer in the subroutine and pass
that back to the calling routine.  Below is an example of
what I am trying to do.  I am using 'sh' for the sake of
the example, but this is where I would be invoking the
database utility and the following 'print XXX "..."' is
where I would I would be passing the database commands.
I can not find another way besides invoking the second
perl script (catcher.pl) to capture the data.

----------------------

#!/export/home/local/bin/perl
use English;

&getTest;

sub getTest
{
open(XXX,"| sh | catcher.pl");
print XXX "echo 'this is a test1'\n";
print XXX "echo 'this is a test2'\n";
print XXX "exit\n";

#I DO NOT WANT TO INVOKE ANOTHER SCRIPT TO
#TO HANDLE THE OUTPUTSTREAM.  I WOULD LIKE TO DO
#SOMETHING LIKE:
#open(XXX,"| sh | @buffer");
#OR
#open(XXX,"| sh | $fileHandle");
#SO THAT I CAN BE ABLE TO LOOP THROUGH AND
#PROCESS THE BUFFER OR FILE HANDLE LATER
#IN THE PROGRAM AND MANIPULATE THE INDIVIDUAL
#OUTPUT ELEMENTS.  BUT HOW DO YOU DO THIS WITHOUT
#INVOKING ANOTHER SCRIPT TO CATCH THE STREAM?
#IDEALLY ALL OF THE OUPUT WOULD BE PIPED TO A
#BUFFER.  THEN I COULD PASS THIS BUFFER BACK TO
#THE CALLING ROUTINE OR ANOTHER SUBROUTINE.

close XXX;
}

-------------catcher.pl--------------

#!/export/home/local/bin/perl
use English;
while (<>)
{
   push @buffer, $_;
}
$cnt=1;
foreach $element (@buffer)
{
   print "LINE $cnt: $element";
   $cnt+=1;
}

---------

Any comments/suggestion/solutions on a better method
of capturing output would be very much appreciated.

Thank you
Michael McGrattan

0
Comment
Question by:mcmike
  • 3
4 Comments
 
LVL 84

Expert Comment

by:ozo
ID: 1205870
One way to do it:

open(XXX,"echo \"echo 'this is a test1'\necho 'this is a test2'\nexit\n\"| sh |") || die $!;
while( <XXX> ){
          print "LINE $.: $_";
}
close XXX or die $!;

Another:

open(XXX,"| sh > catcher.tmp") || die $!
print XXX "echo 'this is a test1'\n";
print XXX "echo 'this is a test2'\n";
print XXX "exit\n";
close XXX or warn $!;
open(XXX,"<catcher.tmp") || die $!;
while( <XXX> ){ ... }

Another:

use IPC::open2;


0
 

Author Comment

by:mcmike
ID: 1205871
Thank you for you input.  I found that the
'use IPC::open2' was what I needed.
This allows me to capture input/output nicely.

Thanks again
Michael McGrattan
0
 
LVL 84

Accepted Solution

by:
ozo earned 100 total points
ID: 1205872
use IPC::Open2;
$pid = open2(\*BUFFER,\*XXX,"sh") || die $!;
print XXX "echo 'this is a test1'\n";
print XXX "echo 'this is a test2'\n";
print XXX "exit\n";
close XXX or warn "error closing |$pid $!";
while( <BUFFER> ){
           print "LINE $.: $_";
}
close BUFFER or warn "error closing $pid| $!";
0
 
LVL 84

Expert Comment

by:ozo
ID: 1205873
or

print XXX <<ZZZ;
echo 'this is a test1'
echo 'this is a test2'
exit
ZZZ


0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question