Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
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 drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2015-07-07 07:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (87 votes), past polls