在 Perl 中获取另一个控制台程序的 I/O 的最佳方法是什么?
What is the preferable way to get the I/O of another console program in Perl?
似乎有两种方法可以在 Perl 中获取另一个程序的 I/O,一种是通过 ` 将程序用参数包围起来,另一种是使用 open
如下所示,这两个之间有什么区别,哪个更好?
# 2 options to get the I/O of another program
1. $output = `program`;
2. open(PIPE, 'program |');
您的第二个案例似乎是通过管道 到 'program',而不是从中接收输入。
如果你的意思是(我认为你是):
open(PIPE, "program |")
那么管道输入的优点是您可以逐个记录地处理,并且您不会一次性消耗整个过程的输出(如第一个场景中发生的那样)。从内存的角度来看,这会更好,如果程序运行很长时间,从时间的角度来看可能会更好。
一种可能性是从 stdin
进行管道传输,然后您可以在命令行上组织您的管道,并在需要时提供额外的过滤等,而不是硬编码对特定二进制文件的依赖。
当您想随时间从进程中读取输出时,管道很有用。假设您要监视日志文件。
例如,您可以这样写:
open(PIPE, 'tail -f log.txt |');
while (<PIPE>) {
chomp;
print("NEW LINE: $_\n");
}
并对添加到日志的每一行执行一些操作。
如果你要写:
$output = `tail -f log.txt`;
println($output);
那么你的程序将永远不会真正到达 println 部分,因为反引号中的命令将等待命令返回。
在 perl 中有很多不同的进程间通信方式 - 多到有一整节的文档perlipc
对于简单的需求,使用什么并不重要。我会说 - 使用上下文中最明显的任何东西。
如果您只是 运行 一个命令并将输出抓取为一个块:
my $df_out = `df -h`;
那我觉得反引号最合适。
如果您想逐行解析 - 反引号 将 起作用,但通常我更喜欢 open
。
例如
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 是值得做的。
似乎有两种方法可以在 Perl 中获取另一个程序的 I/O,一种是通过 ` 将程序用参数包围起来,另一种是使用 open
如下所示,这两个之间有什么区别,哪个更好?
# 2 options to get the I/O of another program
1. $output = `program`;
2. open(PIPE, 'program |');
您的第二个案例似乎是通过管道 到 'program',而不是从中接收输入。
如果你的意思是(我认为你是):
open(PIPE, "program |")
那么管道输入的优点是您可以逐个记录地处理,并且您不会一次性消耗整个过程的输出(如第一个场景中发生的那样)。从内存的角度来看,这会更好,如果程序运行很长时间,从时间的角度来看可能会更好。
一种可能性是从 stdin
进行管道传输,然后您可以在命令行上组织您的管道,并在需要时提供额外的过滤等,而不是硬编码对特定二进制文件的依赖。
当您想随时间从进程中读取输出时,管道很有用。假设您要监视日志文件。
例如,您可以这样写:
open(PIPE, 'tail -f log.txt |');
while (<PIPE>) {
chomp;
print("NEW LINE: $_\n");
}
并对添加到日志的每一行执行一些操作。
如果你要写:
$output = `tail -f log.txt`;
println($output);
那么你的程序将永远不会真正到达 println 部分,因为反引号中的命令将等待命令返回。
在 perl 中有很多不同的进程间通信方式 - 多到有一整节的文档perlipc
对于简单的需求,使用什么并不重要。我会说 - 使用上下文中最明显的任何东西。
如果您只是 运行 一个命令并将输出抓取为一个块:
my $df_out = `df -h`;
那我觉得反引号最合适。
如果您想逐行解析 - 反引号 将 起作用,但通常我更喜欢 open
。
例如
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 是值得做的。