如何从使用su -c的管道中执行的命令获取Perl中的STDERR [英] How to get STDERR in Perl from a command executed in pipe with su -c
问题描述
我的$ command = qq我试图捕获作为不同用户执行的命令的输出(sudo su - < username> -c'/ usr / bin / whatever');
我的$ pid = open $ cmdOutput, - |,$ command;
如何捕获 / usr / bin / code>?
我尝试过
$ pid =打开$ cmdOutput, - |,$ command ||死了出了问题:$!;
但它看起来像是捕获可能的打开本身的错误。
我也尝试过
my $ command = qq(sudo su - < username> -c'/ usr / bin / whatever'2> /tmp/error.message);
这将重定向到文件,我可以稍后解析,但我想要一些更直接
另外,我只想使用核心模块。
p>完全覆盖 在perlfaq8
。由于您正在使用管道打开,所以相关示例是来自核心 open3 .perl.org / IPC / Open3.htmlrel =nofollow noreferrer> IPC :: Open3
模块。
另一个选择是使用 IPC :: Run
来管理你的流程,而 pump
函数将会执行你所需要的。 IPC :: Open3
文档说 IPC :: Run
与您可以根据需要单独或一起操作 STDOUT
和 STDERR
。为了方便和完整的输出捕获,还可以参见 Capture :: Tiny
。
除了 2>输出
重定向,没有更多的基本的方法来管道打开。
如果你不介意混合流或者丢失 STDOUT
另一个选项是
my $ command =' cmd 2>& 1 1> / dev / null'#删除1> / dev / null以使
我的$ pid =打开我的$ cmdOutput, - |,$ command;
while(< $ cmdOutput>){print}#STDERR only
第一个重定向将 STDERR
流与 STDOUT
合并,这样您就可以得到它们,并且混合(使用 STDOUT
受缓冲影响,因此可能会出错)。第二个重定向发送 STDOUT
,所以使用它只是从句柄中只读取命令的 STDERR
p>
问题是使用打开
而运行外部命令, d提到规范和简单的 qx
( backticks )可以以相同的方式使用。它返回 STDOUT
,所以需要如上所述的重定向来获取 STDERR
。为了完整性:
my $ cmd ='cmd_to_execute';
我的$ allout = qx($ cmd 2>& 1); #$ out中的STDOUT和STDERR,或
my $ stderr = qx($ cmd 2>& 1> / dev / null); #只有STDERR
我的$ exit_status = $?
qx
将子进程退出代码(状态)在 $?
中。然后可以检查故障模式;请参阅 qx
页面中的摘要或 perlop中的I / O操作符 。
请注意,以这种方式返回的STDERR
是从命令运行的。如果命令本身无法运行(对于命令名称中的输入错误,或者由于某种原因导致 fork
失败),那么 $?
将是 -1
,错误将在 $!
中。
I'm trying to capture the output of the command executed as a different user using:
my $command = qq(sudo su - <username> -c '/usr/bin/whatever');
my $pid = open $cmdOutput, "-|", $command;
How can I capture the STDERR of /usr/bin/whatever
?
I tried
$pid = open $cmdOutput, "-|", $command || die " something went wrong: $!";
but it looks like this is capturing the possible errors of "open" itself.
I also tried
my $command = qq(sudo su - <username> -c '/usr/bin/whatever' 2>/tmp/error.message);
which will redirect the STDERR to the file, which I can parse later, but I wanted some more straightforward solution.
Also, I only want to use core modules.
This is covered thoroughly in perlfaq8
. Since you are using a piped open, the relevant examples are those that go by open3
from the core IPC::Open3
module.
Another option is to use IPC::Run
for managing your processes, and the pump
function will do what you need. The IPC::Open3
documentation says for IPC::Run
This is a CPAN module that has better error handling and more facilities than Open3.
With either of these you can manipulate STDOUT
and STDERR
separately or together, as needed. For convenient and complete output capture also see Capture::Tiny
.
Other than 2>output
redirection, there are no more elementary methods for the piped open.
If you don't mind mixing the streams or losing STDOUT
altogether, another option is
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
The first redirection merges STDERR
stream with STDOUT
so you get them both, and mixed (with STDOUT
subject to buffering, thus things may well come out of order). The second redirect sends the STDOUT
away so with it in place you read only the command's STDERR
from the handle.
The question is about running an external command using open
but I'd like to mention that the canonical and simple qx
(backticks) can be used in the same way. It returns the STDOUT
so redirection just like above is needed to get STDERR
. For completeness:
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 = $?;
The qx
puts the child process exit code (status) in $?
. This can then be inspected for failure modes; see a summary in the qx
page or a very thorough discussion in I/O operators in perlop.
Note that the STDERR
returned this way is from the command, if it ran. If the command itself couldn't be run (for a typo in command name, or fork
failed for some reason) then $?
will be -1
and the error will be in $!
.
这篇关于如何从使用su -c的管道中执行的命令获取Perl中的STDERR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!