복붙노트

[PYTHON] Python을 통해 Windows 콘솔 응용 프로그램과 상호 작용

PYTHON

Python을 통해 Windows 콘솔 응용 프로그램과 상호 작용

Windows에서 Python 2.5를 사용하고 있습니다. Popen을 통해 콘솔 프로세스와 상호 작용하고 싶습니다. 현재 코드의 작은 스 니펫이 있습니다.

p = Popen( ["console_app.exe"], stdin=PIPE, stdout=PIPE )
# issue command 1...
p.stdin.write( 'command1\n' )
result1 = p.stdout.read() # <---- we never return here
# issue command 2...
p.stdin.write( 'command2\n' )
result2 = p.stdout.read()

stdin에 쓸 수는 있지만 stdout에서 읽을 수는 없습니다. 나는 한 걸음도 놓쳤는가? 프로세스를 종료 할 때 p.communicate ( "command") [0]을 사용하고 싶지 않고 시간이 지남에 따라 프로세스와 동적으로 상호 작용해야합니다.

미리 감사드립니다.

해결법

  1. ==============================

    1.여기서 문제는 대화 형 응용 프로그램을 제어하려고한다는 것입니다.

    여기서 문제는 대화 형 응용 프로그램을 제어하려고한다는 것입니다.

    stdout.read ()는 스트림, 파일 또는 파이프의 끝에 도달 할 때까지 계속 읽습니다. 불행하게도, 대화 형 프로그램의 경우, 파이프는 닫히고 whe 프로그램은 종료됩니다. 그건 당신이 보낸 명령이 "종료"가 아닌 다른 것이라면 결코 그렇지 않습니다.

    stdout.readline ()을 사용하여 서브 프로세스의 출력을 한 행씩 읽는 것으로 되돌려 야하며, 프로그램이 명령을 받아 들일 준비가되어있는 시점과 명령을 발행 한 시점을 알려주는 방법이 더 있어야합니다 프로그램이 완료되면 새 프로그램을 제공 할 수 있습니다. cmd.exe와 같은 프로그램의 경우 새 명령을 보낼 수 있음을 나타내는 줄이 개행 문자로 끝나지 않으므로 readline ()도 충분하지 않으므로 출력을 바이트별로 분석해야합니다. 다음은 cmd.exe를 실행하고 프롬프트를 찾은 다음 dir을 실행 한 다음 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()
    
  2. ==============================

    2.창 끝 줄을 강제로 시도 했습니까? 즉

    창 끝 줄을 강제로 시도 했습니까? 즉

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

    최신 정보:

    방금 cmd.exe Windows에서 솔루션을 확인하고 readline () 함께 작동합니다. 하지만 그것은 Popen의 stdout.readline 블록에 문제가 하나 있습니다. 따라서 응용 프로그램이 endline없이 무언가를 반환한다면 응용 프로그램은 영원히 멈추게됩니다.

    하지만 그 체크 아웃에 대한 해결 방법이 있습니다 : http://code.activestate.com/recipes/440554/

  3. ==============================

    3.readline ()을 대신 사용하려고 할 것 같습니까?

    readline ()을 대신 사용하려고 할 것 같습니까?

    편집 : 미안, 오해.

    어쩌면이 질문이 도움이 될까요?

  4. ==============================

    4.콘솔 응용 프로그램이 출력을 어떤 식 으로든 버퍼링하여 파이프가 닫혀있을 때 stdout에만 보내지는 것이 가능합니까? 콘솔 앱의 코드에 액세스 할 수 있다면 출력 데이터 묶음이 플러시 된 후에 도움을받을 수 있을까요?

    콘솔 응용 프로그램이 출력을 어떤 식 으로든 버퍼링하여 파이프가 닫혀있을 때 stdout에만 보내지는 것이 가능합니까? 콘솔 앱의 코드에 액세스 할 수 있다면 출력 데이터 묶음이 플러시 된 후에 도움을받을 수 있을까요?

    양자 택일로, 실제로 stderr에 쓰고 stdout 대신에 어떤 이유로 기록합니까?

    그냥 코드를 다시보고 다른 것을 생각하면, "command \ n"으로 보내고있는 것을 볼 수 있습니다. 콘솔 앱이 단순히 새 줄 대신 캐리지 리턴 문자를 기다릴 수 있습니까? 어쩌면 출력을하기 전에 콘솔 앱이 명령을 제출할 때까지 기다리는 중일 수 있습니다.

  5. ==============================

    5.여기에서도 똑같은 문제가있었습니다. DrPython 소스 코드를 파고 wx.Execute () 솔루션을 훔쳤습니다. 특히 스크립트가 이미 wx를 사용하고 있다면 잘 작동합니다. 나는 Windows 플랫폼에서 올바른 해결책을 찾지 못했습니다 ...

    여기에서도 똑같은 문제가있었습니다. DrPython 소스 코드를 파고 wx.Execute () 솔루션을 훔쳤습니다. 특히 스크립트가 이미 wx를 사용하고 있다면 잘 작동합니다. 나는 Windows 플랫폼에서 올바른 해결책을 찾지 못했습니다 ...

  6. from https://stackoverflow.com/questions/1124884/interact-with-a-windows-console-application-via-python by cc-by-sa and MIT license