Python постоянный Popen
-
09-09-2019 - |
Вопрос
Есть ли способ выполнить несколько вызовов в одном и том же "сеансе" в Popen?Например, могу ли я выполнить вызов через него, а затем еще один после него без необходимости объединения команд в одну длинную строку?
Решение
Вы не "выполняете вызов", когда используете popen, вы запускаете исполняемый файл и общаетесь с ним через stdin, stdout и stderr.Если у исполняемого файла есть какой-то способ выполнить "сеанс" работы (например, путем чтения строк из stdin), то да, вы можете это сделать.В противном случае вам нужно будет выполнить exec несколько раз.
подпроцесс.Popen - это (в основном) просто оболочка вокруг execvp (3)
Другие советы
Предполагая, что вы хотите иметь возможность запускать оболочку и отправлять ей несколько команд (и читать их выходные данные), похоже, вы можете сделать что-то вроде этого:
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>], [], [])
Например, могу ли я выполнить вызов через него, а затем еще один после него без необходимости объединения команд в одну длинную строку?
Похоже, вы используете shell=True .Не делай этого, если только тебе не нужно.Вместо этого используйте shell=False (по умолчанию) и передайте список команд / аргументов.
Есть ли способ выполнить несколько вызовов в одном и том же "сеансе" в Popen?Например, могу ли я выполнить вызов через него, а затем еще один после него без необходимости объединения команд в одну длинную строку?
Есть ли причина, по которой вы не можете просто создать два экземпляра Popen и ждать / общаться с каждым по мере необходимости?Это обычный способ сделать это, если я вас правильно понял.