如何影响 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 文件句柄。这意味着isatty
在ls
调用它并且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】:我认为$READER
被open3
创建的管道覆盖,这可以通过更改来避免
my $READER = ...;
my $pid = open3(undef, $READER, undef, "/bin/ls");
到
local *READER = ...;
my $pid = open3(undef, '>&READER', undef, "/bin/ls");
请参阅docs。
【讨论】:
谢谢。我曾尝试使用“local $READER”执行此操作几次,但均无效。$READER
是标量。你需要一个球。使用>&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?