似乎有两种方法可以在Perl中获取另一个程序的I / O,一个是通过`的参数包围程序,另一个是使用open
,如下所示,这两者之间有什么区别,哪一个更受欢迎?
# 2 options to get the I/O of another program
1. $output = `program`;
2. open(PIPE, 'program |');
答案 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::Open2
和IPC::Open3
也是允许双向通信的选项。
但有一点需要注意 - 我强烈建议不使用2参数打开,并使用词法文件句柄。培养自己是一个好习惯 - 即使它现在并不重要习惯3-arg open是值得的。