Как мне прочитать вывод терминала в реальном времени из Python?

1

Я пишу программу Python, которая запускает виртуальный терминал. В настоящее время я запускаю его так:

import pexpect, thread

def create_input(child, scrollers, textlength=80, height=12):
    while 1:
        newtext = child.readline()
        print newtext

child = pexpect.spawn("bash", timeout=30000)

thread.start_new_thread(create_input,(child))

Это работает, и я могу отправлять команды ему через child.send(command). Тем не менее, я получаю только целые строки в качестве вывода. Это означает, что если я запускаю что-то вроде Nano или Links, я не получаю никакого вывода, пока процесс не завершится. Я также не вижу, что я набираю, пока не нажимаю кнопку ввода. Есть ли способ прочитать отдельные символы, поскольку bash выводит их?

  • 0
    Вам необходимо сделать вывод «небуферизованным», так как в данный момент он выглядит как «буферизованный строкой».
  • 0
    как я это сделал?
Теги:
multithreading

2 ответа

1
Лучший ответ

Проблема заключается в чем-то другом. Если вы открываете интерактивную оболочку, обычно открывается окно терминала, которое запускает bash, sh, csh или что-то еще. Смотрите слово терминал!

В прежние времена мы подключили терминал к последовательному порту (telnet делает то же самое, что и через ip), снова терминал терминалов.

Даже немой терминал реагирует на коды ESC, сообщает свой тип и устанавливает положение курсора, цвета, очищает экран и т.д.

Таким образом, вы запускаете подпроцесс с интерактивным выходом, но нельзя сказать, что оболочка и подпроцессы относятся к терминалу в этой настройке, отличной от параметров запуска bash, если таковые имеются.

Я предлагаю вам включить telnetd, но только на localhost (127.0.0.1). В рамках вашей программы сделайте сокет и подключитесь к localhost: telnet и посмотрите, как эмулировать правильный терминал. Если программа находится в режиме линии, вы в порядке, но если вы перейдете к полноэкранному редактированию, то вам понадобится массив размером 80x24 или 132x24 или любой другой размер, который вы хотите сохранить своими символами, цветом. Вы также должны иметь возможность сдвигать строки в этом массиве.

Я не смотрел, но я не могу себе представить, что в питоне нет примера telnet-клиента, и терминал emu тоже должен быть там!

Еще одна замечательная вещь: сеансы telnet очищаются, если IP-соединение потеряно, устраняя призрачные процессы.

Мартейн

2

Вам нужно будет изменить вывод любой программы bash, которая будет работать без буферизации, а не буферизации. В хорошем количестве программ есть опция командной строки для небуферизованного вывода.

Ожидаемый проект имеет инструмент под названием unbuffer который выглядит так, как будто он может дать вам весь вывод bash без буферизации. Я лично никогда не использовал его, но здесь есть и другие ответы, которые также рекомендуют: bash: force exec'd process, чтобы иметь unbuffered stdout

  • 0
    Это работает, кроме как для nano, links, vi и т. Д. Vi говорит мне: Vim: Warning: Output is not to a terminal.
  • 0
    @ user677624 Хм, я знаю, что есть способ «подделать», будучи терминалом, чтобы он работал с vi / nano / etc ... Я попытаюсь найти его снова и включить.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню