perl IPC:Open3 最小通过 perlcritic?

Posted

技术标签:

【中文标题】perl IPC:Open3 最小通过 perlcritic?【英文标题】:perl IPC:Open3 minimal to pass perlcritic? 【发布时间】:2014-02-05 16:25:56 【问题描述】:

我正在阅读 perlcritic 文档以避免反引号并在此处使用 IPC::Open3:

http://perl-critic.stacka.to/pod/Perl/Critic/Policy/InputOutput/ProhibitBacktickOperators.html

我正在尝试找到最不冗长的选项,它可以工作并满足 perlcritic:

#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3 'open3'; $SIGCHLD = 'IGNORE';
my $cmd = 'ls';
my ($w,$r,$e); open3($w,$r,$e,$cmd);
my @o = <$r>; my @e = <$e>;
1;

但它抱怨以下错误:

Use of uninitialized value in <HANDLE> at ipc_open3.pl line 7

有什么想法吗?

编辑:好的,这就是我所拥有的。除非有办法简化它,否则我会坚持:

#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open3 'open3'; $SIGCHLD = 'IGNORE';
use Symbol 'gensym';
my $cmd = 'ls';
my ($w,$r,$e) = (undef,undef,gensym); my $p = open3($w,$r,$e,$cmd);
my @o = <$r>; my @e = <$e>;
1;

【问题讨论】:

【参考方案1】:

该页面上的建议很糟糕。 IPC::Open3 是一个难以使用的低级模块。如果将批次发送到 STDERR,页面建议的代码将挂起(死锁)。

请改用IPC::Run3 或IPC::Run。

例子:

run3 $cmd, undef, \my $out, \my $err;
run3 [ $prog, @args ], undef, \my $out, \my $err;
run3 [ $prog, @args ], undef, \my @out, \my @err;

【讨论】:

IPC::Run3 或 IPC::Run 似乎不在我的核心列表中。目前我宁愿坚持使用 corelist。 IPC::Cmd 好用吗?【参考方案2】:

IPC::Open3::open3 的错误参数不应未定义。 synopsis for IPC::Open3 使用 Symbol::gensym 函数预初始化错误参数:

my($wtr, $rdr, $err);
use Symbol 'gensym';
$err = gensym;
$pid = open3($wtr, $rdr, $err, 'some cmd and args', 'optarg', ...);

输入和输出参数可以替换为自动生成的文件句柄,因此可以为这些参数传递undef

当然,这里满足 perlcritic 的最简洁的选项是

my @o = `ls 2>/dev/null`   ## no critic

【讨论】:

当您希望错误出现在 STDERR 上时,最不冗长的选项是忽略此评论家! my @o = &lt;$r&gt;; my @e = &lt;$e&gt;; 可以死锁。如果您要继续使用open3,则需要将它们替换为 IO::Select。

以上是关于perl IPC:Open3 最小通过 perlcritic?的主要内容,如果未能解决你的问题,请参考以下文章

Perl 行为差异关闭由 open() 产生的子进程与 IPC::Open3

如何影响 Perl IPC::Open3 输出的宽度?

为啥 IPC::Open3 调用 cmd.exe 而不是请求的程序?

IPC::Open3 在 Apache 下运行失败

IPC::Open3 转换字符编码

IPC::Open3 的更多麻烦 [重复]