Регистрация выходных данных внешней программы с (wx) python - PullRequest
2 голосов
/ 10 февраля 2009

Я пишу графический интерфейс для использования команд oracle exp / imp и запуска sql-скриптов через sqlplus. Класс подпроцесса позволяет легко запускать команды, но мне нужны некоторые дополнительные функции. Я хочу избавиться от командной строки при использовании моего графического интерфейса wxPython, но мне все еще нужен способ показать вывод команд exp / imp.

Я уже пробовал эти два метода:

command = "exp userid=user/pwd@nsn file=dump.dmp"

process = subprocess.Popen(command, stdout=subprocess.PIPE)
output = process.communicate()[0]

process = subprocess.Popen(command, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.read()

С помощью одного из этих методов (забыл, какой) я действительно получил вывод exp / imp, но только после завершения команды, что для меня совершенно бесполезно, поскольку мне нужно частое обновление во время этих потенциально длительных операций. И sqlplus создал еще больше проблем, так как sqlplus, как правило, требует некоторого ввода при возникновении ошибки. Когда это происходит, python ожидает завершения процесса, но пользователь не видит подсказку, поэтому вы не знаете, сколько еще ждать или что делать ...

То, что я хотел бы иметь - это обертка, которая выводит все, что я вижу в стандартной командной строке. Я хочу записать это в файл и показать его внутри элемента управления wxPython.

Я также попробовал код с этой страницы: http://code.activestate.com/recipes/440554/ но это не может прочитать вывод либо. OutputWrapper из этого ответа также не работает: Как мне перехватить все исключения из приложения wxPython?

Буду признателен за любую помощь!

EDIT:
Подпроцессы не сбрасывают свои выходные данные. Я уже пробовал это с .readline ().
Мой инструмент должен работать на Windows и Unix, поэтому Pexpect не является решением, если нет версии для Windows. А использование cx_oracle было бы чрезмерным излишним, так как мне пришлось бы перестраивать всю функциональность exp, imp и sqlplus.

Ответы [ 4 ]

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

Решением является использование списка для вашей команды

command = ["exp", "userid=user/pwd@nsn", "file=dump.dmp"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)

затем вы читаете process.stdout построчно:

line = process.stdout.readline()

таким образом вы можете обновить графический интерфейс без ожидания. ЕСЛИ запущенный подпроцесс (exp) сбрасывает вывод. Возможно, что выходные данные буферизуются, тогда вы ничего не увидите, пока выходной буфер не будет заполнен. Если это так, то вам, вероятно, не повезло.

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

Если вы работаете в Linux, проверьте pexpect . Это именно то, что вы хотите.

Если вам нужно работать в Windows, возможно, вам следует прикусить пулю и использовать привязки Python к Oracle, такие как cx_Oracle , вместо запуска CL через subprocess.

0 голосов
/ 20 февраля 2009

Могут ли эти решения также захватывать stderr? Я вижу, у вас есть опция stdout = выше. Как вы убедитесь, что получили stderr? Другой вопрос, есть ли способ использовать import logging / import logging.handlers для захвата команды stdout / stderr. Было бы интересно использовать регистратор с его buildt в форматерах / ротаторах и т. Д.

0 голосов
/ 10 февраля 2009

Попробуйте это:

import subprocess

command = "ping google.com"

process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
output = process.stdout
while 1:
    print output.readline(),
...