Использование python для запуска других программ - PullRequest
7 голосов
/ 23 февраля 2010

У меня есть команда, которая прекрасно работает в командной строке. У этого есть много аргументов как cmd --thing foo --stuff bar -a b input output

Я хочу запустить это из python и заблокировать ожидание его завершения. Поскольку скрипт печатает вещи в stdout и stderr, я хочу, чтобы он был немедленно показан пользователю.

Какой модуль подходит для этого?

Я пробовал:


import commands
output = commands.getoutput("cmd --thing foo --stuff bar -a b input output")
print output

это прекрасно работает, за исключением того, что stdout не возвращается до конца.


import os
os.system("cmd --thing foo --stuff bar -a b input output")

выводит все выходные данные, когда cmd фактически завершен.


import subprocess
subprocess.call(["cmd", "--thing foo", "--stuff bar", "-a b", "input", "output"])

это неправильно передает параметры (я не смог найти точную проблему, но cmd отклоняет мои данные). Если в качестве первого параметра указать echo, он выведет команду, которая отлично работает, когда я вставляю ее непосредственно в терминал.


import subprocess
subprocess.call("cmd --thing foo --stuff bar -a b input output")

точно так же, как указано выше.

Ответы [ 4 ]

7 голосов
/ 23 февраля 2010

Вы должны указать каждое поле отдельно, т.е. отделить варианты от их аргументов.

import subprocess
output = subprocess.call(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"])

в противном случае вы эффективно запускаете cmd, как этот

$ cmd --thing\ foo --stuff\ bar -a\ b input output

Чтобы получить вывод в трубу, нужно назвать его немного по-другому

import subprocess
output = subprocess.Popen(["cmd", "--thing", "foo", "--stuff", "bar", "-a", "b", "input", "output"],stdout=subprocess.PIPE)
output.stdout   #  <open file '<fdopen>', mode 'rb'>
3 голосов
/ 23 февраля 2010

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

rc = subprocess.call(
    ["cmd", "--thing", "foo", "--stuff", "bar", 
     "-a", "b", "input", "output"])
print "Return code was", rc

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

Как для показа захвата , так и , кстати, я всегда рекомендую pexpectwexpect в Windows) именно для того, чтобы обойти проблему буферизации.

2 голосов
/ 23 февраля 2010

Не будет работать command.getstatusoutput ()? Он сразу же вернет вам ваш статус.

1 голос
/ 23 февраля 2010

Коллега только что показал мне это:

import os
import sys
for line in os.popen("cmd --thing foo --stuff bar -a b input output", "r"):
    print line
    sys.stdout.flush()

и это работает :) 1004 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...