Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Easy way to capture STDOUT and STDERR without IPC

by rastoboy (Monk)
on Apr 20, 2011 at 16:26 UTC ( #900379=perlquestion: print w/ replies, xml ) Need Help??
rastoboy has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Brothers!

I'm wondering if there is an easy way to execute a shell command and simply capture all of STDERR and STDOUT into a string, potentially without using IPC. I don't need to interact with the process at all, and I find using IPC to be quite awkward/challenging for me. My intuition tells me that there ought to be a simple way to do this, but my knowledge is failing me.

Any input would be greatly appreciated!

Update: Sorry, I meant to say that I wanted to capture STDOUT and STDERR into two separate strings.

Comment on Easy way to capture STDOUT and STDERR without IPC
Re: Easy way to capture STDOUT and STDERR without IPC
by toolic (Chancellor) on Apr 20, 2011 at 16:30 UTC
    From qx:
    To capture a command's STDERR and STDOUT together: 1. $output = `cmd 2>&1`;

    Also from the FAQ's:

    perldoc -q stderr
Re: Easy way to capture STDOUT and STDERR without IPC
by kennethk (Monsignor) on Apr 20, 2011 at 16:33 UTC
    Sure. The easiest way is using backticks (`) - see `STRING` in perlop. Grabbing both STDOUT and STDERR can be done with a little redirection in the shell:  $output = `cmd 2>&1`;
Re: Easy way to capture STDOUT and STDERR without IPC
by eff_i_g (Curate) on Apr 20, 2011 at 17:24 UTC
    If you don't need the entire string and you'd rather loop you can do something like this:
    open my $CMD, '-|', 'ls 2>&1' or die $!; while (<$CMD>) { print if /\.xml/; } close $CMD or die $! ? 'Pipe failed' : 'Program error: ' . ($? >> 8) ;
Re: Easy way to capture STDOUT and STDERR without IPC
by sundialsvc4 (Monsignor) on Apr 20, 2011 at 17:36 UTC

    In a Unix/Linux environment, the so-called “piping” of input/output is ... “the way that things get done in this here neck of the woods.”   Every command has one input stream (STDIN) and two output streams, and the entire system is geared around the notion of doing things by stringing the services of several simpler programs together.   The shell can do it.   Easy as fallin’ off a log...   All the IPC monkey-biz that needs to be done “just happens.”

      So how can you capture STDOUT and STDERR separately?
Re: Easy way to capture STDOUT and STDERR without IPC
by johna (Monk) on Apr 20, 2011 at 20:13 UTC
    Assuming your OS is some *nix flavor, the following might do what you need with a little help from sed:
    #!/usr/bin/perl use strict; use warnings; open my $cmd, "-|", "(SHELL_COMMAND | sed 's/^/stdout:/') 2>&1"; my $stdout; my $stderr; while( <$cmd> ) { if( s/^stdout:// ) { $stdout .= $_; } else { $stderr .= $_; } } close $cmd; print "This is stdout:\n$stdout"; print "This is stderr:\n$stderr";
    It assumes that nothing printed to stderr begins with stdout:. If it does, choose a different string to use.

    -John

Re: Easy way to capture STDOUT and STDERR without IPC
by fidesachates (Monk) on Apr 20, 2011 at 20:27 UTC
    Since no one has stated the obvious, I'll do so. `cmd 2> stderr.txt` By redirecting the stderr into a text file, you'll be able to read the file after the command finishes in perl and your stdout will be captured by the backticks.
Re: Easy way to capture STDOUT and STDERR without IPC
by ikegami (Pope) on Apr 20, 2011 at 20:44 UTC

    I'm wondering if there is an easy way to execute a shell command and simply capture all of STDERR and STDOUT into a string, potentially without using IPC.

    That question makes no sense. "IPC" stands for "Inter-process communication". What do you think you're doing when you're getting data from your child's STDOUT?

    Maybe you're trying to avoid select? Now that's achievable. Just like backticks lets someone else handle the IPC, there are modules that do that for more complicated cases.

    use IPC::Run3 qw( run3 ); run3( \@cmd, undef, \(my $out), \(my $err) );

    IPC::Run3

      You are awesome! IPC::Run3 is just what I needed--easy peasy. Thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://900379]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2014-07-25 07:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (169 votes), past polls