如何在perl中加载STDIN以进行反引号(无需写入临时文件)

时间:2012-04-20 16:31:18

标签: windows perl stdout stdin backticks

我正在执行系统命令,并希望(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,我听说。

感谢。

2 个答案:

答案 0 :(得分:4)

没有理由不在Windows上使用open2。也就是说,open2open3是相当低级的接口,因此它们通常不是任何平台上的最佳选择。

更好的替代方案包括IPC::RunIPC::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;