如何从 Perl 中的外部命令中丢弃 STDERR?

2024-03-10

我想捕获外部命令的退出代码,同时用自定义错误消息替换其标准错误输出。

my $ret = system("which mysql");
if ($ret != 0) {
    say "Error";
}

If mysql可执行文件不存在,它显示which命令错误消息,这是我不想要的。如何摆脱它?


See http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f

如何从外部命令捕获 STDERR?

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

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

使用 system() 时,STDOUT 和 STDERR 都将转到与脚本的 STDOUT 和 STDERR 相同的位置,除非 system() 命令重定向它们。反引号和 open() 仅读取命令的 STDOUT。 您还可以使用 IPC::Open3 中的 open3() 函数。本杰明·戈德堡提供了一些示例代码: 要捕获程序的 STDOUT,但丢弃其 STDERR:

use IPC::Open3;
use File::Spec;
use Symbol qw(gensym);
open(NULL, ">", File::Spec->devnull);
my $pid = open3(gensym, \*PH, ">&NULL", "cmd");
while( <PH> ) { }
waitpid($pid, 0);

要捕获程序的 STDERR,但丢弃其 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);

要捕获程序的 STDERR,并让其 STDOUT 转到我们自己的 STDERR:

use IPC::Open3;
use Symbol qw(gensym);
my $pid = open3(gensym, ">&STDERR", \*PH, "cmd");
while( <PH> ) { }
waitpid($pid, 0);

要分别读取命令的 STDOUT 和 STDERR,您可以将它们重定向到临时文件,让命令运行,然后读取临时文件:

use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHOUT = IO::File->new_tmpfile;
local *CATCHERR = IO::File->new_tmpfile;
my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");
waitpid($pid, 0);
seek $_, 0, 0 for \*CATCHOUT, \*CATCHERR;
while( <CATCHOUT> ) {}
while( <CATCHERR> ) {}

但实际上并不需要两者都是临时文件......以下内容应该同样有效,不会出现死锁:

use IPC::Open3;
use Symbol qw(gensym);
use IO::File;
local *CATCHERR = IO::File->new_tmpfile;
my $pid = open3(gensym, \*CATCHOUT, ">&CATCHERR", "cmd");
while( <CATCHOUT> ) {}
waitpid($pid, 0);
seek CATCHERR, 0, 0;
while( <CATCHERR> ) {}

而且它也会更快,因为我们可以立即开始处理程序的标准输出,而不是等待程序完成。 使用其中任何一个,您都可以在调用之前更改文件描述符:

open(STDOUT, ">logfile");
system("ls");

或者您可以使用 Bourne shell 文件描述符重定向:

$output = `$cmd 2>some_file`;
open (PIPE, "cmd 2>some_file |");

您还可以使用文件描述符重定向来使 STDERR 成为 STDOUT 的副本:

$output = `$cmd 2>&1`;
open (PIPE, "cmd 2>&1 |");

请注意,您不能简单地在 Perl 程序中打开 STDERR 作为 STDOUT 的副本,并避免调用 shell 来执行重定向。这不起作用:

open(STDERR, ">&STDOUT");
$alloutput = `cmd args`;  # stderr still escapes

这会失败,因为 open() 使 STDERR 转到 open() 时 STDOUT 所在的位置。然后反引号使 STDOUT 转到字符串,但不更改 STDERR(它仍然转到旧的 STDOUT)。 请注意,您必须在反引号中使用 Bourne shell (sh(1) ) 重定向语法,而不是 csh(1) !有关为什么 Perl 的 system() 以及反引号和管道打开都使用 Bourne shell 的详细信息,请参阅“远超您想要知道的”集合中的 vs/csh.whynot 文章http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz。要一起捕获命令的 STDERR 和 STDOUT:

$output = `cmd 2>&1`;                       # either with backticks
$pid = open(PH, "cmd 2>&1 |");              # or with an open pipe
while (<PH>) { }                            #    plus a read

要捕获命令的 STDOUT 但丢弃其 STDERR:

$output = `cmd 2>/dev/null`;                # either with backticks
$pid = open(PH, "cmd 2>/dev/null |");       # or with an open pipe
while (<PH>) { }                            #    plus a read

要捕获命令的 STDERR 但丢弃其 STDOUT:

$output = `cmd 2>&1 1>/dev/null`;           # either with backticks
$pid = open(PH, "cmd 2>&1 1>/dev/null |");  # or with an open pipe
while (<PH>) { }                            #    plus a read

要交换命令的 STDOUT 和 STDERR 以捕获 STDERR,但保留其 STDOUT 以显示旧的 STDERR:

$output = `cmd 3>&1 1>&2 2>&3 3>&-`;        # either with backticks
$pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&-|");# or with an open pipe
while (<PH>) { }                            #    plus a read

要分别读取命令的 STDOUT 和 STDERR,最简单的方法是将它们分别重定向到文件,然后在程序完成时从这些文件中读取:

system("program args 1>program.stdout 2>program.stderr");

在所有这些示例中,排序都很重要。这是因为 shell 严格按照从左到右的顺序处理文件描述符重定向。

system("prog args 1>tmpfile 2>&1");
system("prog args 2>&1 1>tmpfile");

第一个命令将标准输出和标准错误发送到临时文件。第二个命令仅发送旧的标准输出,并且旧的标准错误显示在旧的标准输出上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 Perl 中的外部命令中丢弃 STDERR? 的相关文章

  • 如何将 cpanminus 与本地 CPAN::Mini 一起使用?

    我已经创建了自己的 CPAN 本地副本minicpan http search cpan org rjbs CPAN Mini 1 111007 bin minicpan并设法重新配置 cpan 来使用它 太棒了 但是我将如何使用它cpan
  • 使用 Perl 写入文件的最简单方法是什么?

    目前我正在使用 system echo panel login panel password root name root pass port panel type gt gt home shared ftp 使用 Perl 做同样的事情最
  • 在 Objective-C 中使用 perl?

    CPAN 有大量非常有用的库 除了将它们移植到 Objective C 之外 是否还有在 iOS 上将 Perl 代码嵌入到 Objective C 中的方法 我对使用特别感兴趣电子表格 阅读 http kobesearch cpan or
  • 在 Perl 中组装 XML

    我需要对 NetApp 文件管理器进行 API 调用 我知道我需要发送什么原始 XML
  • Perl LWP::简单 HTTPS 错误

    我正在尝试获取网站的内容并打印 该代码按照我希望的方式在常规 HTTP 网站上运行 但它不适用于 HTTPS 我已经查找了此问题的修复程序 但它们在我的程序中不起作用 这是我目前拥有的代码 usr bin perl use strict u
  • 多维哈希排序 - Perl [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我真的需要一些帮助来理解这个哈希并对
  • Perl Moose TypeDecorator 错误。我该如何调试?

    我最近遇到了一个问题 非常感谢您的见解 我在圣诞节前在 PerlMonks 上发布了类似的问题 并提供了一些从 MooseX Declare 切换的反馈 http www perlmonks org node id 877703 1 我现在
  • Perl 中如何释放内存?

    我的代码如下所示 my var my var new while 1 while my k v each var a sub v var A map var var new keys var new var new B sub a sub
  • 如何在没有循环的情况下初始化哈希中的值?

    我正在尝试找出一种无需经过循环即可初始化哈希的方法 我希望使用切片来实现这一点 但它似乎没有产生预期的结果 考虑以下代码 usr bin perl use Data Dumper my hash hash currency symbol B
  • linux + ksh + 向下舍入或向上舍入 - 浮点数

    在我的 ksh 脚本中 我只需要计算整数 有时我会得到浮点数 例如 3 49 或 4 8 等 所以我需要根据以下规则将浮点数转换为整数 示例 3 49 will be 3 2 9 will be 3 4 1 will be 4 23 51
  • 这可以一行完成吗?

    我像这样提取MAC地址 my tmp split domain 123 123 123 123 at 00 11 22 33 44 55 ether on eth0 my vip tmp 3 但不使用临时变量可以完成吗 是的 它可以 my
  • 如何比较两个文件中的多列并在找​​到匹配时从另一列检索相应的值

    我有两个文件 File1 txt 和 File2 txt 我需要将 File1 中的三列 1 2 和 3 分别与 File2 的 4 5 和 6 进行比较 如果找到匹配项 我想从 File2 的第 2 列中检索相应的值并将其粘贴到输出中 T
  • 如何为不同的 Perl 应用程序安装专门的环境?

    就功能而言是否有与 Python 相同或接近的东西虚拟环境 http pypi python org pypi virtualenv what it does 但是对于 Perl 来说呢 我已经用 Python 进行了一些开发 并且将非系统
  • 为什么子程序需要在声明其中使用的变量之后编写?

    假设我们有这段代码 为什么它会因显式包名称错误而失败 因为该函数仅在声明后才被调用 value use strict use warnings sub print value print n value my value 2 print v
  • 如何确保我的代码永远不会直接退出?

    eval require file subsequent code goes here If file包含一个exit语句 后面的代码就没有机会运行 如何解决以便后续代码始终有机会运行eval已经完成了 中止是不可能的exit call f
  • Bugzilla 中分离客户端的基本权限

    我正在尝试配置一个 Bugzilla 实例 这将允许我的客户登录并为其正在开发 维护的网站提交错误 例如 我创建了 2 个名为 TestProject TestProject2 的产品和一个名为 TestClient 的用户 我想要实现的是
  • perl-5.10 之前的高效版本相当于 pack("Q>")

    更新 萨尔瓦正确地指出我对 Q 包模板的介绍是错误的 这是 gt 修饰符 不会返回到 5 8 Perl 5 10 引入了 pack 修饰符 gt 对于我使用 Q 的用例 它将一个无符号四边形 64 位 值打包在大尾数法 现在 我正在寻找一个
  • 当值相同时,为什么我的值比较返回 false?

    我有一个 perl 脚本 可以将 Excel XLS 文件中的数据加载到数据库中 首先 它检查文件中的值的日期时间是否已存在于数据库中 如果是 它会检查文件中的值是否与数据库中的值相同 如果它们相同 则跳过该值 如果不同 则更新数据库中的值
  • 在perl中更改多维哈希的第一个键

    我在 perl 中有一个多维哈希 我想更改所选值的第一个键 例如 我有哈希 my Hash1 Hash1 1 12 1 Hash1 1 10 1 Hash1 2 31 1 Hash1 3 52 1 Hash1 3 58 1 Hash1 4
  • 在 Perl 中如何用空格填充字符串的一部分?

    你更喜欢哪个版本 usr bin env perl use warnings use strict use 5 010 my p 7 33 my prompt my key very important text my value Hell

随机推荐

  • 在 Node.js 中创建 TCP 服务器和 HTTP 服务器之间的 WebSocket

    我创建了一个TCP服务器 using Node js它监听客户端连接 我需要传输数据TCP服务器 to HTTP服务器再次在 Node js 中可能通过网络套接字 套接字 io 但是 我不知道如何创建这样的连接 以便 TCP 服务器能够通过
  • 在 D3.js (V4) 中创建分类折线图

    I m 相对地D3 js 新手 我正在可视化我的 PassengersIn 和 PassengersOut 值总线数据简单 json文件 作为参考 其中一个 JSON 对象如下所示 BusNo 1 Date 21 November 2016
  • 动态添加 Y 轴

    是否可以向 Highstock 图表添加新的 y 轴 我尝试过在选项中添加一个并重新绘制 但这似乎不起作用 HighCharts 的文档包含图表对象的 addAxis 函数 但在 HighStock 中该函数不存在 还有其他选择吗 请看一下
  • TrustZone 监控模式和 IFAR、IFSR、DFAR、DFSR

    The ARM TrustZone 监控模式 http infocenter arm com help index jsp topic com arm doc prd29 genc 009492c CACJBHJA html可以在监视模式下
  • 当前视图控制器不适用于 ios 9

    目前的视图控制器不适用于 ios 9 当我按下按钮时 它没有重定向到当前视图控制器 为什么会出现这种情况 我试过下面的代码 RegistrationViewController viewController UIStoryboard sto
  • 需要将不确定数量的整数从 stdin 读取到数组中

    所以我正在编写一个练习程序 它将整数作为标准输入的输入 将它们加载到数组中 对数组进行排序 然后输出结果 我一直在努力弄清楚 C 中的 IO 是如何工作的 这是我到目前为止所掌握的内容 如果您发现任何问题 有任何建议 请告诉我 理想情况下
  • 使用 TouchHelperCallback 部分和完全滑动 Recyclerview

    我正在尝试使用 api TouchHelperCallback 实现 Recyclerview 的部分和完全滑动 遇到了几个库 例如https github com daimajia AndroidSwipeLayout https git
  • C# 如何用直引号替换微软的智能引号?

    我下面的帖子询问了大引号是什么以及为什么我的应用程序无法使用它们 我现在的问题是当我的程序遇到它们时如何替换它们 我如何在 C 中执行此操作 他们是特殊人物吗 弯引号与方引号的区别 https stackoverflow com quest
  • 在 Angular 中组合路由和查询参数

    在 Angular 中 我必须处理以下格式的路线 sections id filter filter 即我有一个路线参数 id 和查询参数 filter 两个参数都是可选的 因此所有这些路由都是有效的并且正在被监听 sections id
  • 从 unity 运行 python 脚本,以便稍后在我的游戏中使用其输出(文本文件)

    我试图从 unity C 脚本 运行一个 python 脚本 以便稍后在我的游戏中使用它的输出 这是一个文本文件 问题是 当我在 unity 中运行 C 脚本时 没有任何反应 Python 脚本在其上运行良好 自己的 谁能告诉我我错过了什么
  • Material-UI 刷新后崩溃

    我将 Material UI 与 Next js 一起使用 我正在运行npm run dev 我的问题是 每当我按下浏览器上的重新加载按钮时 网站上的样式就会完全破坏 这是正常行为吗 似乎 Material UI 停止工作了 这是我的代码
  • ml-gradle 是否提供任何功能来根据可用区域部署林拓扑?

    ml gradle 是否提供了任何功能 让我可以在考虑可用区的情况下部署副本林拓扑 或者 MarkLogic 提供的任何 API 来了解哪个节点位于哪个可用区 以便我可以为林副本部署定义自己的逻辑 None
  • “Un-Angularize”JS 对象的快速方法

    当使用双向绑定时 Angular 会向我的深层对象结构添加扩展属性 哈希 等 很好 但我有兴趣检索对象树的 JSON 快照 其中仅包含最初属于该对象树的内容 Angular 是否提供了一种获取绑定对象的 普通 版本的方法 我不想在绑定启动之
  • 改造 2 - POST 请求变成了 GET?

    My POST请求继续发送为GET并被 API 端点拒绝 我的服务类 FormUrlEncoded POST api users Call
  • 除非定义 aws-s3 gem? @@{:instance_writer=>true}

    我正在尝试整合aws s3 https github com marcel aws s3gem 使用最新版本的 Rails 4 1 0 启动服务器时我收到此错误 aws s3 0 6 3 lib aws s3 extensions rb 2
  • 获得苹果批准后我们可以拒绝应用程序吗?

    我已经上传了新的二进制文件作为我的应用程序的新版本 在上传二进制文件时 我选择 我将发布此版本 选项 意味着我只是将其放入 保留以供开发人员发布 假设我的应用程序获得了 Apple 的批准 并且我不想发布该版本 那么我必须做什么 是否可以拒
  • Yii:将 JavaScript 添加到标头

    I need
  • 在Prolog中,可以按随机顺序选择解决方案吗?

    如果我有以下情况 a X X 1 X 2 X 3 X 4 我可以按确定性顺序生成解决方案 a X X 1 X 2 X 3 X 4 是否有任何方法可以要求系统以非确定性 随机顺序产生解决方案 例如 a X X 4 X 1 X 3 X 2 我知
  • 如何从控制台应用程序打开WPF窗口[重复]

    这个问题在这里已经有答案了 我刚刚制作了一个简单的控制台应用程序 现在我想打开 WPF 窗口 我将 WPF 项目添加到我的应用程序中 P 但我不知道如何从我的 Main 打开这个窗口 我希望 some1 可以帮助我 Application
  • 如何从 Perl 中的外部命令中丢弃 STDERR?

    我想捕获外部命令的退出代码 同时用自定义错误消息替换其标准错误输出 my ret system which mysql if ret 0 say Error If mysql可执行文件不存在 它显示which命令错误消息 这是我不想要的 如