结合将 open() 重定向到标量与 system()

Combine redirecting open() to scalar with system()

我写了一个例程来“安全地”执行一些命令,我​​想使用 open(STDOUT, '+<', $stdout) 捕获字符串变量中的 STDOUT 和 STDERR 以及类似的 STDERR。 我通过 print "Test\n"print STDERR "Test2\n" 验证了重定向在例程中起作用(我可以在 $stdout$stderr 中找到输出)。

然而,当我通过 system()(Perl 版本)运行 命令时,输出仍然进入终端。 所以我想知道:打开一个标量值是否仅适用于 Perl 自己的 I/O?

如果是这样,我如何在不使用临时文件(有它们自己的问题)的情况下从 system() 调用中捕获 STDOUT 和 STDERR?

(我已经看过 )

首选解决方案(如果存在)应该使用尽可能少的额外包,并且它应该 运行 与 SLES 12 或 SLES 15 (openSUSE Leap 15.2)。 这些发行版仅提供一组有限的 Perl 模块。

您可以使用 IPC::Run 捕获输出轻松做到这一点。

写入标准输出和错误的测试脚本:

#!/bin/sh
# demo.sh
echo "To Standard Output"
echo "To Standard Error" >&2

和运行它的 perl 脚本:

#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Run qw/run/;

my ($out, $err);
run ["sh", "demo.sh"], \undef, $out, $err;
print "Standard output: ", $out;
print "Standard error: ", $err;

给出以下输出:

$ perl demo.pl
Standard output: To Standard Output
Standard error: To Standard Error

使用 IPC::Run3 的替代方案(如果您不需要 IPC::Run 的任何更高级功能,这可能更可取):

#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Run3;

my ($out, $err);
run3 ["sh", "demo.sh"], \undef, $out, $err;
print "Standard output: ", $out;
print "Standard error: ", $err;