2012-06-03 2 views
3

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

UPDATE: я заменил <$READER> с вызовом sysread в надежде, что исходный код может просто иметь проблему буферизации, но вывод, полученный от sysread еще один файл в каждой строке.

UPDATE: Я добавил код, показывающий мою попытку изменить размер IO :: Pty с помощью метода clone_winsize_from. Это не привело к тому, что выход был другим.

UPDATE: Как я могу судить (от чтения 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(); 

ответ

1

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

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

в

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

См docs.

+0

Спасибо. Я пытался сделать это несколько раз с «local $ READER», который не работал. – nall

+1

'$ READER' является скалярным. Вам нужен глобус. Ключ к использованию '> & READER' не является' local', это использование glob. – ikegami

0

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

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

+0

Спасибо. Я это видел и попробовал. Обновленный код в моем вопросе, чтобы отразить попытку. – nall

+0

Обратите внимание, что вызов * * по-прежнему требуется при отключении open3 для fork/exec. – nall

+0

Обновленный ответ с другим предложением. – lanzz

1

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

+0

Спасибо, но/bin/ls - простой пример. Мне нужно решение общего назначения. – nall

Смежные вопросы