在Perl中获取另一个控制台程序的I / O的最佳方法是什么?

时间:2015-02-05 10:48:27

标签: perl

似乎有两种方法可以在Perl中获取另一个程序的I / O,一个是通过`的参数包围程序,另一个是使用open,如下所示,这两者之间有什么区别,哪一个更受欢迎?

# 2 options to get the I/O of another program
1. $output = `program`;
2. open(PIPE, 'program |');

3 个答案:

答案 0 :(得分:2)

您的第二个案例似乎是'程序',而不是接收来自它的输入。

如果你的意思是(我认为你这样做):

open(PIPE, "program |")
然后,管道的优势在于您可以逐个记录处理,并且您不会一次性消耗整个流程的输出(如第一个方案中所示)。从内存的角度来看,如果程序运行很长时间,那么从时间角度来看可能会更好。

可能是从stdin进行管道传输,然后您可以在命令行上组织管道,并在需要时提供额外的过滤等,而不是硬编码对特定二进制文件的依赖。

答案 1 :(得分:1)

当您想要随时间读取进程的输出时,管道非常有用。假设您要监视日志文件。

例如,您可以写:

open(PIPE, 'tail -f log.txt |');

while (<PIPE>) {
    chomp;
    print("NEW LINE: $_\n");
}

并对添加到日志中的每一个新行执行一些操作。

如果你要写:

$output = `tail -f log.txt`;
println($output);

然后你的程序实际上永远不会到达println部分,因为反引号中的命令将一直等到命令返回。

答案 2 :(得分:1)

在perl中的进程之间有很多不同的通信方式 - 很多都有关于它的整个文档部分perlipc

对于简单的要求,使用它并不重要。我会说 - 根据上下文使用最明显的东西。

如果您只是运行一个命令并将输出作为一个块抓取:

my $df_out = `df -h`; 

然后我认为反推是最合适的。

如果您想要逐行解析 - 反叛工作,但通常我会更喜欢open

E.g。

open ( my $ssh_data, "-|", "ssh -n $hostname df" );
my %size_of;
while ( <$ssh_data> ) { 
    my ( $fs, $total, $used, $avail ) = split;
    $size_of{$fs} = $total;
}
close ( $ssh_data ); 

IPC::Open2IPC::Open3也是允许双向通信的选项。

但有一点需要注意 - 我强烈建议使用2参数打开,并使用词法文件句柄。培养自己是一个好习惯 - 即使它现在并不重要习惯3-arg open是值得的。