Взаимодействуйте с консольным приложением Windows с помощью Python

Если Ваша база данных будет проста и проста, LINQ к SQL сделает. При необходимости в логических/абстрактных объектах сверху таблиц то пойдите для Платформы Объекта.

7
задан TravisHendrickson 17 April 2013 в 03:36
поделиться

5 ответов

Проблема в том, что вы пытаетесь управлять интерактивным приложением.

stdout.read () будет продолжать чтение, пока не достигнет конца потока, файла или труба. К сожалению, в случае интерактивной программы канал закрывается только тогда, когда программа завершается; что никогда, если вы отправили команду, отличную от "quit" .

Вам придется вернуться к чтению вывода подпроцесса построчно, используя stdout. readline () , и вам лучше иметь способ узнать, когда программа готова принять команду, и когда команда, которую вы отправили программе, завершена, и вы можете предоставить новую. В случае такой программы, как cmd.exe , даже readline () победил. t достаточно, так как строка, указывающая на возможность отправки новой команды, не заканчивается символом новой строки, поэтому необходимо будет анализировать вывод побайтно. Вот пример сценария, который запускает cmd.exe , ищет приглашение, затем выдает каталог , а затем exit :

from subprocess import *
import re

class InteractiveCommand:
    def __init__(self, process, prompt):
        self.process = process
        self.prompt  = prompt
        self.output  = ""
        self.wait_for_prompt()

    def wait_for_prompt(self):
        while not self.prompt.search(self.output):
            c = self.process.stdout.read(1)
            if c == "":
                break
            self.output += c

        # Now we're at a prompt; clear the output buffer and return its contents
        tmp = self.output
        self.output = ""
        return tmp

    def command(self, command):
        self.process.stdin.write(command + "\n")
        return self.wait_for_prompt()

p      = Popen( ["cmd.exe"], stdin=PIPE, stdout=PIPE )
prompt = re.compile(r"^C:\\.*>", re.M)
cmd    = InteractiveCommand(p, prompt)

listing = cmd.command("dir")
cmd.command("exit")

print listing

Если время не ' Это важно, и интерактивность для пользователя не требуется, может быть намного проще просто объединить вызовы:

from subprocess import *

p = Popen( ["cmd.exe"], stdin=PIPE, stdout=PIPE )
p.stdin.write("dir\n")
p.stdin.write("exit\n")

print p.stdout.read()
7
ответ дан 7 December 2019 в 03:19
поделиться

Я думаю, вы могли бы попробовать вместо этого использовать readline ()?

Изменить: извините, непонятно.

Может быть этот вопрос может вам помочь?

0
ответ дан 7 December 2019 в 03:19
поделиться

Вы пытались принудительно установить оконечные линии окон? i.e.

p.stdin.write( 'command1 \r\n' )
p.stdout.readline()

UPDATE:

I've just checked the solution on windows cmd.exe and it works with readline(). But it has one problem Popen's stdout.readline blocks. So if the app will ever return something without endline your app will stuck forever.

But there is a work around for that check out: http://code.activestate.com/recipes/440554/

2
ответ дан 7 December 2019 в 03:19
поделиться

Возможно ли, что консольное приложение каким-то образом буферизует свой вывод так, что он отправляется на стандартный вывод только при закрытии канала? Если у вас есть доступ к коду для консольного приложения, может быть, может помочь установка сброса после пакета выходных данных?

Или же, действительно ли он по какой-то причине пишет в stderr, а не в stdout?

Просто посмотрел на ваш код снова и подумал о чем-то еще, я вижу, вы отправляете "команду \ n". Может ли консольное приложение просто ждать символа возврата каретки вместо новой строки? Возможно, консольное приложение ждет, пока вы отправите команду, прежде чем оно выдаст какой-либо результат.

действительно ли он по какой-то причине пишет в stderr, а не в stdout?

Просто посмотрел на ваш код еще раз и подумал о другом, я вижу, вы отправляете "command \ n". Может ли консольное приложение просто ждать символа возврата каретки вместо новой строки? Возможно, консольное приложение ждет, пока вы отправите команду, прежде чем оно выдаст какой-либо результат.

он действительно пишет в stderr и вместо stdout по какой-то причине?

Просто взглянул на ваш код еще раз и подумал о другом, я вижу, вы отправляете "command \ n". Может ли консольное приложение просто ждать символа возврата каретки вместо новой строки? Возможно, консольное приложение ждет, пока вы отправите команду, прежде чем оно выдаст какой-либо результат.

0
ответ дан 7 December 2019 в 03:19
поделиться

Здесь была точно такая же проблема. Я покопался в исходном коде DrPython и украл решение wx.Execute () , которое работает нормально, особенно если ваш скрипт уже использует wx. Я так и не нашел правильного решения на платформе Windows ...

0
ответ дан 7 December 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: