почему subprocess.Popen (...) не всегда возвращается? - PullRequest
6 голосов
/ 29 марта 2009

Надеюсь, это простой вопрос по питону.

Когда я пытаюсь сделать следующее в интерпретаторе python:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd)
...
>>> test(['ls', '-l'])

Он запустит ls -l, но мне нужно нажать «return», чтобы получить новое приглашение >>>.

Однако, когда я пытаюсь сделать следующее:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd)
...   p.wait()
...
>>> test(['ls', '-l'])

Затем ls -l будет запущен с приглашением >>> сразу.

Еще один вариант:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
...
>>> test(['ls', '-l'])

Это даст мне немедленное новое приглашение.

Последний пример ближе всего к тому, что я хочу. Моя цель - запустить дочерний процесс, дождаться его завершения, а затем использовать его стандартный вывод в моем родительском процессе, обратившись к p.stdout, позволяя stderr просто печатать туда, где он был бы иначе.

Прямо сейчас в моем реальном приложении последняя версия просто висит на: p = subprocess.Popen(cmd, stdout=subprocess.PIPE) с или без p.wait().

Спасибо

Charlie

Ответы [ 4 ]

8 голосов
/ 29 марта 2009

В первом варианте test() возвращается сразу после запуска процесса, но до его вывода на консоль.

Если вы посмотрите на вывод, вы do получите запрос, непосредственно перед выводом ls.

>>> test(['ls', '-l'])
>>> total 0                            <----- test() returns, new propmpt
--rw-r--r--    1 foo bar   7 Mar 24 17:38
etc etc

Во втором варианте test() ожидает завершения процесса, прежде чем он вернется.

В третьей версии вы правы, что вам может потребоваться прочитать из дочернего процесса stdout, чтобы продолжить.

7 голосов
/ 29 марта 2009

Возможно, я ответил на свой вопрос. Я считаю, что в последнем случае мне нужно явно прочитать из p.stdout для продолжения моего процесса.

е:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.stdout.readlines()
....

Спасибо всем

0 голосов
/ 22 августа 2014

Вот команда, которая пингует Google навсегда, поэтому ее необходимо вручную прекратить, чтобы получить выходные данные.

Инструкции по преобразованию вызовов метода os.popen () в полные подпроцессы содержатся в документации .

.
host = "www.google.com"
command = "ping %s -t"%host

#p = os.popen(command) -- using Popen instead of os.popen() to allow calling terminate()
p = Popen(command, stdout=subprocess.PIPE)

time.sleep(5)
print "term"
p.terminate()
pingResultSoFar = p.communicate()[0] # get what has been printed to standard out so far
print pingResultSoFar
0 голосов
/ 20 февраля 2014

Просто используйте метод connect (). Нет необходимости возвращать.

>>> test(['ls', '-l'])
>>> 
>>> def test(cmd):
...    p = subprocess.Popen(cmd).communicate()
... 
>>> test(['ls', '-l'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...