我有以下urwid程序,它显示按下的键或来自Popen'd程序的任何行:
#!/usr/bin/env python
import urwid
from threading import Thread
from subprocess import Popen, PIPE
import time
import os
class MyText(urwid.Text):
def __init__(self):
super(MyText, self).__init__('Press Q to quit', align='center')
def selectable(self):
return True
def keypress(self, size, key):
if key in ['q', 'Q']:
raise urwid.ExitMainLoop()
else:
self.set_text(repr(key))
class Writer(object):
def __init__(self):
self._child = Popen(
'for i in `seq 5`; do sleep 1; echo $i; done',
#"ssh localhost 'for i in `seq 5`; do sleep 1; echo $i; done'",
shell=True, stdout=PIPE, stderr=PIPE)
def file(self):
return self._child.stdout
def fileno(self):
return self._child.stdout.fileno()
w = Writer()
txt = MyText()
top = urwid.Filler(txt)
mainloop = urwid.MainLoop(top)
def on_writer():
c = w.file().read(1)
if c == '': # terminated
mainloop.remove_watch_file(w.fileno())
return
if c == '\n':
return
txt.set_text(c)
mainloop.draw_screen()
mainloop.watch_file(w.fileno(), on_writer)
mainloop.run()上面的程序可以工作,但如果我将Popen'd命令更改为ssh localhost ...版本,程序将停止显示按键,直到ssh localhost ...命令结束。为什么会这样呢?
环境:Python6.6,CentOS 2.7.4,urwid 1.3.1-dev。
发布于 2014-11-20 01:55:55
问题是ssh试图操作它的stdin。将其stdin设置为虚拟文件描述符可以解决此问题。
class Writer(object):
def __init__(self):
r, w = os.pipe()
self._child = Popen(
#'for i in `seq 5`; do sleep 1; echo $i; done',
"ssh localhost 'for i in `seq 5`; do sleep 1; echo $i; done'",
shell=True, stdin=r, stdout=PIPE, stderr=PIPE)
os.close(w)https://stackoverflow.com/questions/27022810
复制相似问题