the*_*ory 16 perl ipc pipe filehandle
我想创建一个简单的IO对象,它表示打开到另一个程序的管道,我可以在我的应用程序运行时定期写入另一个程序的STDIN.我希望它能够防弹(因为它可以捕获所有错误)和跨平台.我能找到的最佳选择是:
open
sub io_read {
local $SIG{__WARN__} = sub { }; # Silence warning.
open my $pipe, '|-', @_ or die "Cannot exec $_[0]: $!\n";
return $pipe;
}
Run Code Online (Sandbox Code Playgroud)
好处:
缺点
$SIG{PIPE}
从管道程序捕获错误sub io_read {
IO::Pipe->reader(@_);
}
Run Code Online (Sandbox Code Playgroud)
好处:
缺点
$SIG{PIPE}
从管道程序中捕获错误在IPC :: Run中没有用于写入文件句柄的接口,只是附加到标量.这似乎......很奇怪.
这里也没有文件句柄接口.我可以使用代码引用,它将被重复调用以假脱机到子代,但是看看源代码,它似乎实际写入临时文件,然后打开它并将其内容假脱机到管道命令STDIN
.世界卫生大会?
仍然没有文件句柄接口.
我在这里错过了什么?似乎这应该是一个已经解决的问题,而且我有点惊讶它不是.IO :: Pipe最接近我想要的,但缺乏$SIG{PIPE}
错误处理和缺乏对Windows的支持是令人痛苦的.JDWIM的管道模块在哪里?
感谢@ikegami的指导,我发现在Perl中以交互方式读取和写入另一个进程的最佳选择是IPC :: Run.但是,它要求您正在读取和写入的程序在写入其STDOUT时具有已知输出,例如提示.这是一个执行的示例,bash
运行它ls -l
,然后打印输出:
use v5.14;
use IPC::Run qw(start timeout new_appender new_chunker);
my @command = qw(bash);
# Connect to the other program.
my ($in, @out);
my $ipc = start \@command,
'<' => new_appender("echo __END__\n"), \$in,
'>' => new_chunker, sub { push @out, @_ },
timeout(10) or die "Error: $?\n";
# Send it a command and wait until it has received it.
$in .= "ls -l\n";
$ipc->pump while length $in;
# Wait until our end-of-output string appears.
$ipc->pump until @out && @out[-1] =~ /__END__\n/m;
pop @out;
say @out;
Run Code Online (Sandbox Code Playgroud)
因为它是作为IPC运行的(我假设),bash
所以在写入STDOUT时不会发出提示.所以我使用new_appender()
函数让它发出一些我可以匹配的东西来找到输出的结尾(通过调用echo __END__
).我在调用之后还使用了一个匿名子例程new_chunker
来将输出收集到数组中,而不是标量('>'
如果你想要的话,只需将标量的引用传递给它).
所以这很有效,但在我看来,它有很多原因:
__END__
).如果我在控制数据库客户端,我可能需要发送类似的东西SELECT 'IM OUTTA HERE';
.不同的应用需要不同的new_appender
黑客攻击.$in
和$out
标量的写作感觉很奇怪,并且在远处行动.我不喜欢它.new_chunker
如果仍然有点奇怪,使用获取面向行的输出的能力是很好的.然而,假设它被IPC :: Run有效缓冲,那么重新获得了从程序读取输出的效率.我现在意识到,尽管IPC :: Run的界面可能会更好一些,但总体而言,IPC模型的弱点使得处理它变得棘手.没有通用的IPC接口,因为人们必须对运行的特定程序的具体细节了解太多才能使其工作.这是正常的,也许,如果你知道它究竟是如何给输入的反应,而当它完成发射输出能够可靠地识别,并且不需要得多担心跨平台的兼容性.但这远远不足以满足我对CPAN模块中各种数据库命令行客户端进行交互的通用方法的需求,这些客户端可以分发到整个操作系统主机.
最后,由于博客文章评论中的打包建议,我决定放弃使用IPC来控制这些客户端,而是使用DBI.它提供了出色的API,强大,稳定,成熟,并且没有IPC的缺点.
我对那些追随我的人的建议如下:
归档时间: |
|
查看次数: |
2084 次 |
最近记录: |