题
在 Perl 脚本的中间,有一个我要执行的系统命令。我有一个字符串,其中包含需要输入到 stdin 的数据(该命令仅接受来自 stdin 的输入),并且我需要捕获写入 stdout 的输出。我研究了在 Perl 中执行系统命令的各种方法,以及 open
function 似乎是我所需要的,只是看起来我只能捕获 stdin 或 stdout,而不能同时捕获两者。
目前,我最好的解决方案似乎是使用 open
, ,将 stdout 重定向到临时文件,并在命令完成后从文件中读取。有更好的解决方案吗?
解决方案
我想你想看看 IPC::打开2
其他提示
IPC::Open2/3 很好,但我发现通常我真正需要的是 IPC::运行3, ,它以最小的复杂性很好地处理了简单的情况:
use IPC::Run3; # Exports run3() by default
run3( \@cmd, \$in, \$out, \$err );
该文档将 IPC::Run3 与其他替代方案进行了比较。即使您不决定使用它,也值得一读。
这 Perlipc 文档 涵盖了执行此操作的多种方法,包括 IPC::Open2 和 IPC::Open3。
在脚本顶部的某个位置,包含以下行
use IPC::Open2;
这将包括必要的模块,通常默认情况下随大多数 Perl 发行版一起安装。(如果没有,可以使用 CPAN 安装它。)然后,不要打开,而是调用:
$pid = open2($cmd_out, $cmd_in, 'some cmd and args');
您可以通过将数据发送到 $cmd_in 来将数据发送到命令,然后通过从 $cmd_out 读取来读取命令的输出。
如果您还希望能够读取命令的 stderr 流,则可以使用 IPC::Open3 模块。
IPC::Open3 可能会做你想做的事。它可以捕获 STDERR 和 STDOUT。
我最近发现的一个非常简单的方法是 这 IPC::过滤器 模块. 。它可以让您非常直观地完成工作:
$output = filter $input, 'somecmd', '--with', 'various=args', '--etc';
请注意,如果您向它传递一个列表,它如何在不通过 shell 的情况下调用您的命令。它还可以合理地处理常见实用程序的错误。(失败时, die
s,使用 STDERR 中的文本作为其错误消息;成功后,STDERR 将被丢弃。)
当然,它不适合大量数据,因为它没有提供任何流处理的方法;此外,错误处理可能不够精细,无法满足您的需求。但它却让许多简单的案例真正 真的 简单的。
有一个专门的 perl 命令可以解决这个问题
open2()
更多信息可以在以下位置找到: http://sunsite.ualberta.ca/Documentation/Misc/perl-5.6.1/lib/IPC/Open2.html
如果你不想包含额外的包,你可以这样做
open(TMP,">tmpfile");
print TMP $tmpdata ;
open(RES,"$yourcommand|");
$res = "" ;
while(<RES>){
$res .= $_ ;
}
这与您的建议相反,但也应该有效。
如果我只期望单行输出或者想要将结果拆分为换行符以外的其他内容,我总是这样做:
my $result = qx( command args 2>&1 );
my $rc=$?;
# $rc >> 8 is the exit code of the called program.
if ($rc != 0 ) {
error();
}
如果要处理多行响应,请将结果作为数组获取:
my @lines = qx( command args 2>&1 );
foreach ( my $line ) (@lines) {
if ( $line =~ /some pattern/ ) {
do_something();
}
}