3

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

更新:<$READER>用一个调用替换了,sysread希望原始代码可能只是有缓冲问题,但从接收的输出sysread仍然是每行一个文件。

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

更新:据我所知(通过阅读 1.12 版的 IPC::open3 代码),您似乎无法在不open3创建管道而不是dup文件句柄的情况下传递 IO::Handle 类型的变量。这意味着在调用它isatty时不返回真值,然后强制自己进入“每行一个文件”模式。lsls

我想我只需要自己做一个 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();
4

3 回答 3

2

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

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

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

请参阅文档

于 2012-06-04T06:00:27.370 回答
1

您可以通过-C选项来ls强制它使用列输出(不IO::Pty涉及)。

于 2012-06-03T22:09:57.570 回答
0

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

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

于 2012-06-03T21:59:11.470 回答