3

I'm executing a system command, and wanting to (1) pre-load STDIN for the system command and (2) capture the STDOUT from the command.

Per here I see I can do this:

open(SPLAT, "stuff")   || die "can't open stuff: $!";
open(STDIN, "<&SPLAT") || die "can't dupe SPLAT: $!";
print STDOUT `sort`;

This uses the currently defined STDIN as STDIN for the sort. That's great if I have the data in a file, but I have it in a variable. Is there a way I can load the contents of the variable into STDIN before executing the system command? Something like:

open(STDIN, "<$myvariable"); # I know this syntax is not right, but you get the idea
print STDOUT `sort`;

Can this be done without using a temp file? Also, I'm in Windows, so Open2 is not recommended, I hear.

Thanks.

Jonathan M
  • 17,145
  • 9
  • 58
  • 91

2 Answers2

4

There's no reason not to use open2 on Windows. That said, open2 and open3 are rather low-level interfaces, so they're usually not the best choice on any platform.

Better alternatives include IPC::Run and IPC::Run3. IPC::Run is a bit more powerful than IPC::Run3, but the latter is a bit simpler to use.

May I recommend

use IPC::Run3 qw( run3 );
my $stdin = ...;
run3([ 'sort' ], \$stdin, \my $stdout);

It even does error checking for you.


But since you mentioned open2,

use IPC::Open2 qw( open2 );
my $stdin =...;
my $pid = open2(\local *TO_CHILD, \local *FROM_CHILD, 'sort');
print TO_CHILD $stdin;
close TO_CHILD;
my $stdout = '';
$stdout .= $_ while <FROM_CHILD>;
waitpid($pid);
die $? if $?;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks. I really like the simplicity of `Run3`, especially since I'm not needing a bunch of functionality. Very compact. – Jonathan M Apr 20 '12 at 17:54
  • do you happen to know if ActiveState has an equivalent to IPC::Run3? I don't see it in their ppm listing. Maybe it's the `IPC::Cmd` ? – Jonathan M Apr 20 '12 at 18:51
  • Either it does or it doesn't. A different module isn't equivalent. That said, it IS available in AS's 5.14.2 32-bit repo, and you could always install it using `cpan IPC::Run3`. – ikegami Apr 20 '12 at 19:40
2

Maybe IPC::Open2 didn't work so well on Windows 15 years ago, but I wouldn't expect you to have any trouble with it now.

use IPC::Open2;
my $pid = open2( \*SORT_OUT, \*SORT_IN, 'sort' );
print SORT_IN $sort_input;  # or  @sort_input
close SORT_IN;
print "The sorted output is: ", <SORT_OUT>;
close SORT_OUT;
mob
  • 117,087
  • 18
  • 149
  • 283