обнаружение конца вывода tty - PullRequest
1 голос
/ 17 февраля 2010

Привет, я пишу псевдо-терминал, который может жить в tty и порождать второй tty, который фильтрует ввод и вывод из

Я сейчас пишу это на python, порождаю второй tty, а читать и писать легко

но когда я читаю, чтение не заканчивается, оно ждет большего ввода.

import subprocess

pfd = subprocess.Popen(['/bin/sh'], shell=True, 
    stdout=subprocess.PIPE, stdin=subprocess.PIPE)

cmd = "ls" 

pfd.stdin.write(cmd + '\n')

out = ''
while 1: 
    c = pfd.stdout.read(1)
    if not c: # if end of output (this never happends)
        break 
    if c == '\n': # print line when found
        print repr(out)
        out = ''
    else:
        out += c

----------------------------- выходы ----------------- -------

intty $ python intty.py 
'intty.py'
'testA_blank'
'testB_blank'
(hangs here does not return)

похоже, что он достигает конца буфера и вместо возврата None или '' зависает в ожидании большего ввода.

что я должен искать, чтобы увидеть, завершен ли вывод? конец буфера? непечатный символ?

---------------- редактировать -------------

это происходит также, когда я запускаю xpcshell вместо ls, я предполагаю, что у этих интерактивных программ есть некоторый способ узнать, чтобы снова отобразить приглашение, душно подсказка, в этом случае "js>" никогда не появляется

Ответы [ 2 ]

1 голос
/ 17 февраля 2010

Ну, ваш вывод фактически не завершен. Поскольку вы породили /bin/sh, оболочка все еще работает после завершения "ls". Индикатор EOF отсутствует, потому что он все еще работает.

Почему бы просто не запустить /bin/ls?

Вы могли бы сделать что-то вроде

pfd = subprocess.Popen(['ls'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)

out, err_output = pfd.communicate()

Это также выделяет subprocess.communicate, который является более безопасным способом получения выходных данных (для выходов, которые в любом случае помещаются в память) из одного запуска программы. Он вернется только после завершения работы программы.

С другой стороны, вы могли бы читать также из оболочки, но вы искали бы специальную последовательность оболочки, такую ​​как строка sh~#, которая могла бы легко появиться в выходных данных программы. Таким образом, запуск оболочки, вероятно, является плохой идеей.


Редактировать Вот то, что я имел в виду, но на самом деле это не самое лучшее решение, поскольку у него МНОГО предостережений:

while 1: 
    c = pfd.stdout.read(1)
    if not c:
        break
    elif c == '\n': # print line when found
        print repr(out)
        out = ''
    else:
        out += c
        if out.strip() == 'sh#':
            break

Обратите внимание, что это произойдет, если любая другая команда выведет 'sh #' в начале строки, а также если по какой-либо причине выходные данные отличаются от ожидаемых, вы войдете в ту же ситуацию блокировки, что и раньше. Вот почему это очень неоптимальная ситуация для оболочки.

0 голосов
/ 17 февраля 2010

Для таких приложений, как оболочка, вывод не завершится, пока оболочка не завершится. Либо используйте select.select(), чтобы проверить, не ждет ли вас больше выходных данных, либо завершите процесс.

...