当前位置:  开发笔记 > 编程语言 > 正文

你如何在Perl中同时捕获stderr,stdout和退出代码?

如何解决《你如何在Perl中同时捕获stderr,stdout和退出代码?》经验,为你挑选了4个好方法。

是否可以从Perl运行外部进程,捕获其stderr,stdout和进程退出代码?

我似乎能够组合这些,例如使用反引号来获取stdout,使用IPC :: Open3来捕获输出,使用system()来获取退出代码.

你如何一次捕获stderr,stdout和退出代码?



1> xdg..:

(更新:我更新了IO :: CaptureOutput的API,使其更加简单.)

有几种方法可以做到这一点.这是一个选项,使用IO :: CaptureOutput模块:

use IO::CaptureOutput qw/capture_exec/;

my ($stdout, $stderr, $success, $exit_code) = capture_exec( @cmd );

这是capture_exec()函数,但IO :: CaptureOutput还有一个更通用的capture()函数,可用于捕获Perl输出或外部程序的输出.因此,如果某些Perl模块碰巧使用了一些外部程序,您仍然可以获得输出.

它还意味着您只需要记住捕获STDOUT和STDERR(或合并它们)的单一方法,而不是使用IPC :: Open3来获取外部程序和其他模块来捕获Perl输出.


它似乎[Capture :: Tiny](http://search.cpan.org/dist/Capture-Tiny/)更新更好:'这个模块的灵感来自IO :: CaptureOutput,它提供了类似的功能而没有能力开发输出和更复杂的代码和API.IO :: CaptureOutput不处理"限制"部分中描述的图层或大多数异常情况,我不再推荐它. - http://search.cpan.org/~dagolden/Capture-Tiny-0.18/lib/Capture/Tiny.pm#SEE_ALSO
@PhilipDurbin很有趣,这个答案的作者和Capture :: Tiny的作者是同一个人.:)

2> Michael Carm..:

如果您重读了IPC :: Open3的文档,您将看到一条注释,您应该调用waitpid来获取子进程.完成此操作后,状态应该可用$?.退出值是$? >> 8.见 $?perldoc perlvar.


我已经给perl5porters发送了一个补丁到IPC :: Open2和:: Open3,以显示这些模块的概要中的waitpid内容.:)

3> pjf..:

如果你不想要STDERR的内容,那么来自IPC :: System :: Simple模块的capture()命令几乎就是你所追求的:

   use IPC::System::Simple qw(capture system $EXITVAL);

   my $output = capture($cmd, @args);

   my $exit_value = $EXITVAL;

您可以使用带有单个参数的capture()来调用shell,也可以使用多个参数来可靠地避免使用shell.还有capturex(),它永远不会调用shell,即使只有一个参数.

与Perl的内置系统和反引号命令不同,IPC :: System :: Simple在Windows下返回完整的32位退出值.如果命令无法启动,信号死亡或返回意外退出值,它也会抛出详细的异常.这意味着对于许多程序而言,您可以依靠IPC :: System :: Simple为您做出艰苦的工作,而不是自己检查退出值:

 use IPC::System::Simple qw(system capture $EXIT_ANY);

 system( [0,1], "frobincate", @files);     # Must return exitval 0 or 1

 my @lines = capture($EXIT_ANY, "baznicate", @files);  # Any exitval is OK.

 foreach my $record (@lines) {
     system( [0, 32], "barnicate", $record);  # Must return exitval 0 or 32
 }

IPC :: System :: Simple是纯Perl,没有依赖关系,适用于Unix和Windows系统.不幸的是,它没有提供捕获STDERR的方法,因此它可能不适合您的所有需求.

IPC :: Run3提供了一个干净简单的界面来重新管理所有三个常见的文件句柄,但不幸的是它没有检查命令是否成功,所以你需要检查$?手动,这一点都不好玩.提供检查$的公共界面?因为检查$?是我在 TM :: System :: Simple 的待办事项清单上的东西.跨平台的方式不是我希望任何人的任务.

IPC ::名称空间中还有其他模块也可以为您提供帮助.因人而异.

祝一切顺利,

保罗



4> hoyhoy..:

运行外部命令有三种基本方法:

system $cmd;        # using system()
$output = `$cmd`;       # using backticks (``)
open (PIPE, "cmd |");   # using open()

有了system(),两者STDOUT和STDERR将与脚本相同STDOUT,STDERR,除非system()命令重定向它们.反引号并open()只读取STDOUT你的命令.

你也可以拨打像张开以下重定向都STDOUTSTDERR.

open(PIPE, "cmd 2>&1 |");

返回代码始终存储在@Michael Carman$?所指出的位置.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有