如何在 perl 中为反引号加载 STDIN(不写入临时文件)
Posted
技术标签:
【中文标题】如何在 perl 中为反引号加载 STDIN(不写入临时文件)【英文标题】:How to load STDIN for a backtick in perl (without writing to a temp file) 【发布时间】:2012-04-20 16:31:18 【问题描述】:我正在执行一个系统命令,并且想要 (1) 为系统命令预加载 STDIN 并 (2) 从命令中捕获 STDOUT。
根据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,我听说。
谢谢。
【问题讨论】:
【参考方案1】:没有理由不在 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 $?;
【讨论】:
谢谢。我真的很喜欢Run3
的简单性,尤其是因为我不需要一堆功能。非常紧凑。
您是否知道 ActiveState 是否具有与 IPC::Run3 等价的功能?我在他们的 ppm 列表中没有看到它。也许是IPC::Cmd
?
要么有,要么没有。不同的模块是不等价的。也就是说,它在 AS 的 5.14.2 32 位 repo 中可用,您始终可以使用 cpan IPC::Run3
安装它。【参考方案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;
【讨论】:
感谢您让我直接了解 Open2 在 Windows 上的可用性。好答案。 +1。以上是关于如何在 perl 中为反引号加载 STDIN(不写入临时文件)的主要内容,如果未能解决你的问题,请参考以下文章