Как я могу влиять на ширину вывода Perl IPC::Open3?

У меня есть следующий код Perl, и я хотел бы, чтобы он отображался точно так же, как вызывающий /bin/ls в терминале будет отображаться. Например, на терминале размером до 100 столбцов перед выводом новой строки будет напечатан вывод до 100 символов. Вместо этого этот код печатает 1 файл на строку вывода. Я чувствую, что это предполагает назначение некоторых настроек терминала IO::Pty Например, но я попробовал варианты этого без удачи.

ОБНОВЛЕНИЕ: я заменил <$READER> с призывом к sysread надеясь, что исходный код может иметь проблемы с буферизацией, но вывод получен из sysread по-прежнему один файл в строке.

ОБНОВЛЕНИЕ: я добавил код, показывающий мою попытку изменить размер IO::Pty через clone_winsize_from метод. Это не привело к тому, что результат был другим.

ОБНОВЛЕНИЕ: Как я могу сказать (из чтения кода IPC::open3 для версии 1.12), кажется, что вы не можете передать переменную типа IO::Handle без open3 создавая трубу, а не dupОбработка файлового дескриптора. Это означает isatty не возвращает истинное значение, когда ls вызывает это и ls затем принудительно переключается в режим "один файл на строку".

Я думаю, что мне просто нужно сделать fork/exec и самостоятельно обработать перенаправление ввода / вывода.

#!/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();

3 ответа

Решение

Я думаю $READER перезаписывается с помощью трубы, созданной open3, чего можно избежать, изменив

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

в

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

Смотрите документы.

Вы можете передать -C возможность ls заставить его использовать столбчатый вывод (не получая IO::Pty участвует).

Документы IO::Pty описывают clone_winsize_from(\*FH) метод. Вы можете попробовать клонировать размеры вашего фактического pty.

Я вижу, что вы настраиваете pty только как stdout детского процесса. Возможно, вам придется настроить его также как его stdin - когда дочерний процесс отправляет escape-последовательность "Размер терминала запроса" в свою stdout, он должен был бы получить ответ на свой stdin,

Другие вопросы по тегам