2012-04-20 31 views
3

我执行系统命令,并且希望(1)预加载STDIN为系统命令(2)捕获STDOUT从命令。如何加载STDIN用于在Perl反引号(没有写入临时文件)

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,我听说。

谢谢。

回答

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 $?; 
+0

谢谢。我非常喜欢'Run3'的简单性,特别是因为我不需要大量的功能。非常紧凑。 – 2012-04-20 17:54:53

+0

你碰巧知道如果ActiveState公司有相当于IPC :: RUN3?我没有看到它在ppm列表中。也许它是'IPC :: Cmd'? – 2012-04-20 18:51:05

+0

它可以或不可以。不同的模块并不等同。这就是说,它是在AS的5.14.2 32位回购可用,你总是可以使用'CPAN IPC :: Run3'安装。 – ikegami 2012-04-20 19:40:05

2

也许IPC::Open2没有在Windows上工作,以及15年前,但我不希望你有任何麻烦了。

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; 
+0

感谢直设置我的Open2的Windows上的易用性。好答案。 +1。 – 2012-04-20 17:55:23