如何影响 Perl IPC::Open3 输出的宽度?

Posted

技术标签:

【中文标题】如何影响 Perl IPC::Open3 输出的宽度?【英文标题】:How do I influence the width of Perl IPC::Open3 output? 【发布时间】:2012-06-03 19:30:21 【问题描述】:

我有以下 Perl 代码,并希望它完全显示在终端中调用 /bin/ls 会显示。例如,在一个大小为 100 列的终端上,它会在插入换行符之前打印多达 100 个字符的输出。相反,此代码每行输出打印 1 个文件。我觉得这涉及将一些终端设置分配给IO::Pty 实例,但我尝试了一些变体但没有运气。

更新:我将 <$READER> 替换为对 sysread 的调用,希望原始代码可能只是存在缓冲问题,但从 sysread 收到的输出仍然是每行一个文件.

更新:我添加了显示我尝试通过 clone_winsize_from 方法更改 IO::Pty 大小的代码。这并没有导致输出有任何不同。

更新:据我所知(通过阅读 1.12 版的 IPC::open3 代码),如果没有 open3 创建管道,您似乎无法传递 IO::Handle 类型的变量比dup'ing 文件句柄。这意味着isattyls 调用它并且ls 然后强制自己进入“每行一个文件”模式时不会返回真值。

我想我只需要执行一个 fork/exec 并自己处理 I/O 重定向。

#!/usr/bin/env perl
use IPC::Open3;
use IO::Pty;
use strict;

my $READER = IO::Pty->new();
$READER->slave->clone_winsize_from(\*STDIN);

my $pid = open3(undef, $READER, undef, "/bin/ls");

while(my $line = <$READER>)

    print $line;

waitpid($pid, 0) or die "Error waiting for pid: $!\n";

$READER->close();

【问题讨论】:

【参考方案1】:

我认为$READERopen3 创建的管道覆盖,这可以通过更改来避免

my $READER = ...;
my $pid = open3(undef, $READER, undef, "/bin/ls");

local *READER = ...;
my $pid = open3(undef, '>&READER', undef, "/bin/ls");

请参阅docs。

【讨论】:

谢谢。我曾尝试使用“local $READER”执行此操作几次,但均无效。 $READER 是标量。你需要一个球。使用&gt;&amp;READER 的关键不是local,而是使用glob。【参考方案2】:

您可以将-C 选项传递给ls 以强制它使用列输出(不涉及IO::Pty)。

【讨论】:

谢谢,但 /bin/ls 只是一个简单的例子。我需要一个通用解决方案。【参考方案3】:

IO::Pty docs 描述了一个clone_winsize_from(\*FH) 方法。您可以尝试克隆您实际 pty 的尺寸。

我看到您将pty 设置为子进程的stdout。您可能还需要将其设置为 stdin — 当子进程将“查询终端大小”转义序列发送到其 stdout 时,它需要在其 stdin 上接收响应。

【讨论】:

谢谢。我看到并尝试过。更新了我的问题中的代码以反映尝试。 请注意,在为 fork/exec 避开 open3 时仍需要调用 用另一个建议更新了答案。

以上是关于如何影响 Perl IPC::Open3 输出的宽度?的主要内容,如果未能解决你的问题,请参考以下文章

我们在 C 或 C++ 中是不是有类似于 IPC::Open3 的 perl

perl IPC:Open3 最小通过 perlcritic?

为啥 IPC::Open3 调用 cmd.exe 而不是请求的程序?

IPC::Open3 的更多麻烦 [重复]

IPC::Open3 在 Apache 下运行失败

如何检查使用 IPC::open3 执行的命令是不是挂起?