capturing STDOUT from and piped "into" program

Discussion in 'Perl Misc' started by Tim, May 1, 2007.

  1. Tim

    Tim Guest

    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;
    Tim, May 1, 2007
    #1
    1. Advertising

  2. Tim

    Paul Lalli Guest

    On May 1, 4:33 pm, Tim <> wrote:
    > 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
    Paul Lalli, May 1, 2007
    #2
    1. Advertising

  3. Tim

    Guest

    Tim <> wrote:
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 1, 2007
    #3
  4. Tim

    Tim Guest

    On May 1, 2:48 pm, wrote:
    > Tim <> wrote:
    > > 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
    >
    > --
    > --------------------http://NewsReader.Com/--------------------
    > Usenet Newsgroup Service $9.95/Month 30GB



    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
    Tim, May 2, 2007
    #4
  5. Tim

    Guest

    Tim <> wrote:
    > On May 1, 2:48 pm, wrote:
    > > Tim <> wrote:
    > > > 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
    > >
    > > --
    > > --------------------http://NewsReader.Com/--------------------
    > > Usenet Newsgroup Service $9.95/Month 30GB

    >
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 2, 2007
    #5
  6. Tim

    Tim Guest

    On May 1, 2:35 pm, Paul Lalli <> wrote:
    > On May 1, 4:33 pm, Tim <> wrote:
    >
    >
    >
    > > 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



    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
    Tim, May 2, 2007
    #6
  7. Tim

    Tim Guest


    > 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
    >


    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
    Tim, May 2, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fuzzyman
    Replies:
    3
    Views:
    634
    Gabriel Genellina
    Jan 7, 2007
  2. Venks
    Replies:
    10
    Views:
    228
    MonkeeSage
    Dec 7, 2007
  3. rihad

    re-launch piped external program

    rihad, Sep 21, 2007, in forum: Perl Misc
    Replies:
    14
    Views:
    179
    Mumia W.
    Sep 25, 2007
  4. Mahesh Asolkar

    How to know if data is piped into my script

    Mahesh Asolkar, Apr 15, 2008, in forum: Perl Misc
    Replies:
    3
    Views:
    97
    nntpman68
    Apr 16, 2008
  5. Mike

    capturing stdout and stderr?

    Mike, Aug 9, 2009, in forum: Perl Misc
    Replies:
    0
    Views:
    98
Loading...

Share This Page