Питон настойчивый попен - PullRequest
3 голосов
/ 26 февраля 2009

Есть ли способ сделать несколько звонков в одной и той же "сессии" в Popen? Например, могу ли я сделать вызов через него, а затем еще один после него, не объединяя команды в одну длинную строку?

Ответы [ 3 ]

3 голосов
/ 26 февраля 2009

Вы не «звоните», когда используете popen, вы запускаете исполняемый файл и говорите с ним через stdin, stdout и stderr. Если исполняемый файл имеет какой-либо способ выполнения «сеанса» работы (например, путем чтения строк из stdin), тогда да, вы можете это сделать. В противном случае вам нужно будет выполнить несколько раз.

subprocess.Popen - это (в основном) просто оболочка для execvp (3)

1 голос
/ 26 февраля 2009

Предполагая, что вы хотите иметь возможность запускать оболочку и отправлять ей несколько команд (и читать их вывод), похоже, вы можете сделать что-то вроде этого:

from subprocess import *
p = Popen(['/bin/sh'], shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)

После чего, например:

>>> p.stdin.write("cat /etc/motd\n")
>>> p.stdout.readline()
'Welcome to dev-linux.mongo.com.\n'

(Конечно, вы должны также проверить stderr или попросить Popen объединить его с stdout). Одна из основных проблем с вышеприведенным заключается в том, что каналы stdin и stdout находятся в режиме блокировки, поэтому легко застрять, ожидая вывода из оболочки навсегда. Хотя я еще не пробовал, на сайте ActiveState есть рецепт , который показывает, как решить эту проблему.

Обновление : после просмотра связанных вопросов / ответов может показаться, что проще использовать встроенный в Python модуль select, чтобы посмотреть, есть ли данные для чтения stdout ( Вы также должны сделать то же самое для stderr, конечно), например:

>>> select.select([p.stdout], [], [], 0)
([<open file '<fdopen>', mode 'rb' at 0x10341690>], [], [])
0 голосов
/ 26 февраля 2009

Например, могу ли я сделать вызов через него, а затем еще один после него, не объединяя команды в одну длинную строку?

Похоже, вы используете shell = True. Не, если вам не нужно. Вместо этого используйте shell = False (по умолчанию) и передайте список команд / аргументов.

Есть ли способ сделать несколько звонков в одной и той же "сессии" в Popen? Например, могу ли я сделать вызов через него, а затем еще один после него, не объединяя команды в одну длинную строку?

По какой причине вы не можете просто создать два экземпляра Popen и ждать / общаться с каждым по мере необходимости? Это нормальный способ сделать это, если я вас правильно понимаю.

...