Solved

Using Perl open with pipes

Posted on 1997-08-30
4
475 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
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…

685 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