And*_*sev 5 perl perl-critic ipcopen3
我想在子进程中压缩输出并只读取stderr.perlfaq8建议做以下事项:
# To capture a program's STDERR, but discard its STDOUT:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, ">&NULL", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);
Run Code Online (Sandbox Code Playgroud)
但后来perlcritic争论使用裸字文件句柄.
我唯一可以设计的是将select新打开的描述符/dev/null改为on STDOUT,如下所示:
# To capture a program's STDERR, but discard its STDOUT:
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open my $null, ">", File::Spec->devnull;
my $old_stdout = select( $null );
my $pid = open3(gensym, ">&STDOUT", \*PH, "cmd");
select( $old_stdout );
while( <PH> ) { }
waitpid($pid, 0);
Run Code Online (Sandbox Code Playgroud)
但后来perlcritic不喜欢使用select.有更优雅的解决方案吗?
小智 3
最小的更改只是将 open 中的 NULL 更改为 *NULL,使其不再是裸词。
使用这种形式的句柄通常仍然被认为是不好的形式(因为它们是全局变量,尽管您可以通过对它们应用 local 来使它们稍微不那么全局)。所以我建议将其更改为对所有句柄使用我的变量。看起来您正在丢弃标准输入文件句柄,因此也可以传递空文件句柄(请注意,我正在以读写模式打开它)
use strict;
use warnings;
use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(my $null, '+>', File::Spec->devnull);
my $childErr = gensym;
my $pid = open3($null, $null, $childErr, "cmd");
while(<$childErr>) { }
waitpid($pid, 0);
Run Code Online (Sandbox Code Playgroud)