如何将 Perl 的 system() 的输出重定向到文件句柄?

Posted

技术标签:

【中文标题】如何将 Perl 的 system() 的输出重定向到文件句柄?【英文标题】:How can I redirect the output of Perl's system() to a filehandle? 【发布时间】:2010-04-27 05:52:05 【问题描述】:

通过 Perl 中的open 命令,您可以使用文件句柄。但是我无法在 Perl 中使用 open 命令取回退出代码。

使用 Perl 中的system 命令,我可以取回正在运行的程序的退出代码。但是我只想将 STDOUT 重定向到某个文件句柄(没有 stderr)。

我的标准输出将是键值对的逐行输出,我想将其插入到 perl 中的 mao 中。这就是为什么我只想从 perl 中的 Java 程序重定向我的标准输出。这可能吗?

注意:如果我收到错误,错误会打印到 stderr。一种可能性是检查是否有任何内容打印到 stderr,以便我可以完全使用 Perl 脚本。

【问题讨论】:

你尝试过什么?任何代码。 我有。我得到的最接近的是 open 函数。理想情况下,使用 Perl 中的 open 函数从我的 Java 程序中获取退出代码会很棒。 Octopus 要求查看显示您尝试过的示例代码。如果我们没有看到,我们无法告诉您您的代码有什么问题。 【参考方案1】:

典型地,如果您试图获取分叉进程的文本输出,我的理解是这就是反引号的用途。如果你也需要退出状态,你可以在之后用$?特殊变量检查它,例如:

open my $fh, '>', "output.txt" or die $!;
print $fh `echo "Hello!"`;
print "Return code: $?\n";

不会捕获从反引号命令到 STDERR 的输出,而是直接写入调用它的 Perl 程序中的 STDERR。

【讨论】:

【参考方案2】:

您可能想查看IPC::System::Simple——它为您提供了许多用于执行外部命令、捕获其输出和返回值以及在返回错误结果时选择死亡的选项。

【讨论】:

【参考方案3】:

这是其中一种方法。

open my $fh, '>', $file;
defined(my $pid = fork) or die "fork: $!";
if (!$pid) 
    open STDOUT, '>&', $fh;
    exec($command, @args);

waitpid $pid, 0;
print $? == 0 ? "ok\n" : "nok\n";

【讨论】:

别忘了关闭$fh ...并恢复 STDOUT?【参考方案4】:

-| 模式下使用open。当你close文件句柄时,退出状态将在$?

open my $fh, '-|', "$command";  # older version:  open my $fh, "$command |";
my @command_output = <$fh>;
close $fh;
my $command_status = $?;

来自perldoc -f close

如果文件句柄来自管道打开,"close" 将 如果其他系统调用之一,则另外返回 false 涉及失败,或者程序以非零状态退出。 (如果唯一的问题是程序以非零值退出,$! 将被设置为 0。)关闭管道也会等待进程 在管道上执行以完成,以防您想查看 之后管道的输出,并隐式放置出口 该命令的状态值转换为$?"$^CHILD_ERROR_NATIVE".

【讨论】:

严格来说,问题在于如何将命令的输出重定向到已经打开的文件句柄,而不是如何捕获它。 @codeholic - 严格来说,OP 的第二句话表示有兴趣从open 语句中获取退出代码。 OP 认识到有很多方法可以完成这项任务,并且很好地避免了“我如何使用 X 来完成 Y?”问题类型。 严格来说,第二句中的open 是没有兴趣的。退出代码应该已经得到了,怎么做都没关系。

以上是关于如何将 Perl 的 system() 的输出重定向到文件句柄?的主要内容,如果未能解决你的问题,请参考以下文章

Perl 的 system() 如何打印它正在运行的命令?

在 Perl 中使用 nohup 时如何抑制系统输出?

如何以跨平台方式管道传输两个 Perl CORE::system 命令?

具有多个参数的 Perl 系统命令输出到文件

Linux 第三天 重定负管道符环境变量

将 sqlplus 命令的输出保存到数组中的任何可能方法 - Perl