На платформе posix-y (в основном на любой популярной платформе, кроме Windows) модуль select предлагает подходящие инструменты для этой цели. К сожалению, в Windows select
работает только на сокетах (а не на каналах, которыми будет пользоваться subprocess.Popen
), поэтому ситуация здесь не совсем ясна. Вам нужно запустить на Windows ...?
Если нет, просто используйте p.stdout.fileno()
вашего объекта подпроцесса p
в вызове select.select
с коротким тайм-аутом - это действительно просто!
Редактировать : вот простой пример (конечно, при условии необходимого импорта):
>>> def f():
... p = subprocess.Popen("sleep 10; echo ciao", shell=True, stdout=subprocess.PIPE)
... while True:
... r, w, x = select.select([p.stdout.fileno()],[],[],1.0)
... if r: return p.stdout.read()
... print 'not ready yet'
...
>>> f()
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
'ciao\n'
>>>
Заметьте, что нет способа "ждать полной строки": это ожидает "любого вывода вообще" (затем блокирует, пока все выходные данные не будут готовы). Чтобы прочитать только то, что доступно, используйте fcntl , чтобы установить os.O_NODELAY в дескрипторе файла (что возвращает fileno()
), прежде чем начинать цикл.