gpt4 book ai didi

perl - 如何从使用 su -c 在管道中执行的命令中获取 Perl 中的 STDERR

转载 作者:行者123 更新时间:2023-12-03 07:46:38 25 4
gpt4 key购买 nike

我正在尝试使用以下命令捕获以不同用户身份执行的命令的输出:

my $command = qq(sudo su - <username> -c '/usr/bin/whatever');
my $pid = open $cmdOutput, "-|", $command;

如何捕获 /usr/bin/whatever 的 STDERR ?

我试过
$pid = open $cmdOutput, "-|", $command || die " something went wrong: $!";

但看起来这正在捕捉“打开”本身可能出现的错误。

我也试过
my $command = qq(sudo su - <username> -c '/usr/bin/whatever' 2>/tmp/error.message);

这会将 STDERR 重定向到文件,稍后我可以解析该文件,但我想要一些更直接的解决方案。

另外,我只想使用核心模块。

最佳答案

这被彻底覆盖了in perlfaq8 .由于您使用的是管道打开,因此相关示例是 open3 中的示例。来自核心 IPC::Open3模块。

另一种选择是使用 IPC::Run用于管理您的流程,以及 pump功能会做你需要的。 IPC::Open3文档说 IPC::Run

This is a CPAN module that has better error handling and more facilities than Open3.



使用其中任何一个,您都可以操作 STDOUTSTDERR根据需要单独或一起。如需方便和完整的输出捕获,另请参阅 Capture::Tiny .

除了 2>output重定向,管道打开没有更多的基本方法。

如果您不介意混合流或丢失 STDOUT总的来说,另一种选择是
my $command = 'cmd 2>&1 1>/dev/null'          # Remove 1>/dev/null to have both
my $pid = open my $cmdOutput, "-|", $command;

while (<$cmdOutput>) { print } # STDERR only

第一次重定向合并 STDERR使用 STDOUT 串流所以你得到它们,并混合(与 STDOUT 受缓冲,因此事情很可能会出现问题)。第二个重定向发送 STDOUT离开,所以你只阅读命令的 STDERR从 handle 。

问题是关于使用 open 运行外部命令。但我想提一下,规范而简单的 qx (反引号)可以以相同的方式使用。它返回 STDOUT所以需要像上面一样的重定向来获得 STDERR .为了完整性:
my $cmd = 'cmd_to_execute';
my $allout = qx($cmd 2>&1); # Both STDOUT and STDERR in $out, or
my $stderr = qx($cmd 2>&1 1>/dev/null); # Only STDERR
my $exit_status = $?;
qx将子进程退出代码(状态)放入 $? .然后可以检查故障模式;参见 qx 中的摘要页面或在 I/O operators in perlop 中进行非常彻底的讨论.

请注意 STDERR如果它运行,则以这种方式返回来自命令。如果命令本身无法运行(由于命令名称中的拼写错误,或 fork 由于某种原因失败),则 $?将是 -1错误将出现在 $! .

关于perl - 如何从使用 su -c 在管道中执行的命令中获取 Perl 中的 STDERR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38218998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com