我正在执行系统命令,并希望(1)为系统命令预加载STDIN,以及(2)从命令中捕获STDOUT。
Per here我知道我可以这样做:
open(SPLAT, "stuff") || die "can't open stuff: $!";
open(STDIN, "<&SPLAT") || die "can't dupe SPLAT: $!";
print STDOUT `sort`;
这使用当前定义的STDIN作为排序的STDIN。如果我在一个文件中有数据,这很好,但我把它放在一个变量中。有没有办法在执行系统命令之前将变量的内容加载到STDIN中?类似的东西:
open(STDIN, "<$myvariable"); # I know this syntax is not right, but you get the idea
print STDOUT `sort`;
这可以在不使用临时文件的情况下完成吗?另外,我在Windows中,所以不建议使用Open2,我听说。
感谢。
答案 0 :(得分:4)
没有理由不在Windows上使用open2
。也就是说,open2
和open3
是相当低级的接口,因此它们通常不是任何平台上的最佳选择。
更好的替代方案包括IPC::Run和IPC::Run3。 IPC :: Run比IPC :: Run3更强大,但后者使用起来更简单。
我可以推荐
use IPC::Run3 qw( run3 );
my $stdin = ...;
run3([ 'sort' ], \$stdin, \my $stdout);
它甚至会为您进行错误检查。
但是你提到了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 $?;
答案 1 :(得分:2)
也许IPC::Open2
在15年前在Windows上运行得不好,但我不希望你现在遇到任何麻烦。
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;