2012-04-20 40 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