Я пишу программу 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 выводит их?
Проблема заключается в чем-то другом. Если вы открываете интерактивную оболочку, обычно открывается окно терминала, которое запускает bash, sh, csh или что-то еще. Смотрите слово терминал!
В прежние времена мы подключили терминал к последовательному порту (telnet делает то же самое, что и через ip), снова терминал терминалов.
Даже немой терминал реагирует на коды ESC, сообщает свой тип и устанавливает положение курсора, цвета, очищает экран и т.д.
Таким образом, вы запускаете подпроцесс с интерактивным выходом, но нельзя сказать, что оболочка и подпроцессы относятся к терминалу в этой настройке, отличной от параметров запуска bash, если таковые имеются.
Я предлагаю вам включить telnetd, но только на localhost (127.0.0.1). В рамках вашей программы сделайте сокет и подключитесь к localhost: telnet и посмотрите, как эмулировать правильный терминал. Если программа находится в режиме линии, вы в порядке, но если вы перейдете к полноэкранному редактированию, то вам понадобится массив размером 80x24 или 132x24 или любой другой размер, который вы хотите сохранить своими символами, цветом. Вы также должны иметь возможность сдвигать строки в этом массиве.
Я не смотрел, но я не могу себе представить, что в питоне нет примера telnet-клиента, и терминал emu тоже должен быть там!
Еще одна замечательная вещь: сеансы telnet очищаются, если IP-соединение потеряно, устраняя призрачные процессы.
Мартейн
Вам нужно будет изменить вывод любой программы bash, которая будет работать без буферизации, а не буферизации. В хорошем количестве программ есть опция командной строки для небуферизованного вывода.
Ожидаемый проект имеет инструмент под названием unbuffer
который выглядит так, как будто он может дать вам весь вывод bash без буферизации. Я лично никогда не использовал его, но здесь есть и другие ответы, которые также рекомендуют: bash: force exec'd process, чтобы иметь unbuffered stdout
Vim: Warning: Output is not to a terminal.