我有以下Perl代码,并且希望它显示为在终端中显示的调用/bin/ls
。例如,在大小为100列的终端上,在插入换行符之前,它最多可打印100个字符的输出。相反,此代码每行输出打印1个文件。我觉得这涉及到为IO::Pty
实例分配一些终端设置,但我尝试了没有运气的变体。
更新:我通过调用<$READER>
取代sysread
,希望原始代码可能只有缓冲问题,但是从sysread
收到的输出每行仍然是一个文件。
更新:我添加了代码,显示我尝试通过clone_winsize_from
方法更改IO :: Pty的大小。这并没有导致输出有任何不同。
更新:我可以告诉(从读取版本1.12的IPC :: open3代码),似乎你不能传递IO :: Handle类型的变量而不用open3
创建一个管道而不是dup
'文件句柄。这意味着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();
答案 0 :(得分:2)
我认为$READER
被open3
创建的管道覆盖,可以通过更改
my $READER = ...;
my $pid = open3(undef, $READER, undef, "/bin/ls");
到
local *READER = ...;
my $pid = open3(undef, '>&READER', undef, "/bin/ls");
请参阅docs。
答案 1 :(得分:1)
您可以将-C
选项传递给ls
以强制它使用列式输出(不涉及IO::Pty
)。
答案 2 :(得分:0)
IO::Pty docs描述了clone_winsize_from(\*FH)
方法。您可以尝试克隆实际的pty维度。
我发现您将pty
仅设置为子进程的stdout
。您可能还需要将其设置为stdin
- 当子进程将“查询终端大小”转义序列发送到其stdout
时,它需要在其stdin
上接收响应}。