Потоковая передача stdin / stdout в Python - PullRequest
4 голосов
/ 19 ноября 2011

Я пытаюсь передать потоковую оболочку bash в / из простого пользовательского интерфейса WebSockets, но у меня возникают проблемы с перенаправлением ввода-вывода. Я хочу запустить экземпляр bash и подключить stdout и stdin к функциям write_message () и on_message (), которые взаимодействуют с моим веб-интерфейсом. Вот упрощенная версия того, что я пытаюсь сделать:

class Handler(WebSocketHandler):
    def open(self):
        print "New connection opened."
        self.app = subprocess.Popen(["/bin/bash", "--norc", "-i"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=False)
        thread.start_new_thread(self.io_loop, ())

    def on_message(self, message):
        self.app.stdin.write(message)

    def on_close(self):
        self.app.terminate()

    def io_loop(self):
        while self.app.poll() is None:
            line = self.app.stdout.readline()
            if line:
                self.write_message(line)

Несмотря на то, что bash запускается и вызывается on_message, я не получаю никакого вывода. readline () остается блокирующим. Я пробовал stdout.read (), stdout.read (1) и различные модификации буфера, но все еще не выводил. Я также попробовал жестко запрограммировать команды с завершающим символом '\ n' в on_message, чтобы изолировать проблему, но я до сих пор не получаю никакого вывода из readline ().

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

1 Ответ

3 голосов
/ 19 ноября 2011

Это выглядит как строка:

line = self.app.stdout.readline()

заблокирует запуск ioloop, поскольку приложение будет проводить большую часть своего времени в зависании в readline(), ожидая, пока приложение запишет какой-нибудь выводвместо.Чтобы это сработало, вам нужно получить stdin и stdout процесса (а как насчет stderr? - вам тоже нужно это захватить), переключить их в неблокирующий режим идобавьте их к набору файловых дескрипторов, на которые ioloop тратит свое время.

...