Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

feeding text to a process, and capturing its output, safely

by merlyn (Sage)
on Mar 23, 2004 at 17:43 UTC ( #339092=snippet: print w/ replies, xml ) Need Help??

Description: When you have program data that must be fed as the standard input to a process, and you want to capture its output, and you want to avoid the shell, it's time for a double fork!
my @INPUT = (... many lines of text ...);
my @COMMAND = qw(tr a-zA-Z A-Za-z); # swap lower/upper case
my @RESULT; # this is where the result will go...
if (open RESULT, "-|") { # original process
  @RESULT = <RESULT>;
} else { # child
  if (open STDIN, "-|") { # child
    exec @COMMAND;
    die "Cannot exec: $!";
  } else { # grandchild
    print @INPUT;
    exit 0;
  }
}
Comment on feeding text to a process, and capturing its output, safely
Download Code
Re: feeding text to a process, and capturing its output, safely
by QM (Vicar) on Mar 23, 2004 at 19:49 UTC
    Can you comment on the "safely" aspect of this?

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

      Yes.

      Oh, you mean will I elaborate?

      OK.

      No shell is involved. This makes it safer than the solutions I've seen that usually end up as something like:

      my @RESULT = `echo $INPUT | Some Command`;
      The problem is that $INPUT is being handed to a shell, making me have to worry and wonder about all shell-sensitive characters.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        Thanks, I had forgotten about that.

        I should think this method might be preferred then, unless the application is something quick-and-dirty.

        Will you please comment on the disadvantages of this method?

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Re: feeding text to a process, and capturing its output, safely
by Anonymous Monk on Mar 24, 2004 at 07:50 UTC

    Do you have a Win32 version of this as well?

Re: feeding text to a process, and capturing its output, safely
by duelafn (Priest) on Jun 09, 2011 at 16:10 UTC

    Converted to a subroutine, make the exec safer, optionally capture STDERR, lexical filehandle:

    =head3 safe_pipe safe_pipe [ options, ] command, input my $results = safe_pipe [ 'command', 'arg' ], @input; my @results = safe_pipe [ 'command', 'arg' ], @input; my $results = safe_pipe { capture_err => 1 }, [ 'command', 'arg' ], @ +input; Pipe data to a shell command safely (without touching a command line) +and retrieve the results. Options: =over 4 =item capture_err If true, STDERR will also be captured and included in returned results +. =back =cut sub safe_pipe { my $opt = {}; $opt = shift if 'HASH' eq ref($_[0]); my $command = shift; my ($RESULT, @x); $command = [$command] unless ref $command; if (open $RESULT, "-|") { # original process: receiver (reads $RESUL +T) @x = <$RESULT>; } else { if (open STDIN, "-|") { # child: processor (reads STDIN, writes ST +DOUT) open STDERR, ">&STDOUT" or die "Can't dup STDOUT: $!" if $$opt{c +apture_err}; exec { $$command[0] } @$command; die "Cannot exec @$command: $!"; } else { # grandchild: sender (writes STDOUT) print @_; exit 0; } } wantarray ? @x : join('', @x); }

    Good Day,
        Dean

Back to Snippets Section

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2014-12-28 22:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (183 votes), past polls