2009-07-14 4 views
7

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

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() 

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

미리 감사드립니다.

+0

귀하의 코드가 올바른 것입니다. 콘솔에서 실행하면 console_app가 제대로 작동합니까? 그것은 command1에 대해 무엇을 반환합니까? – luc

+0

예 cmd.exe에서 실행하면 console_app가 정상적으로 작동합니다. 제공된 입력 (그리고 때로는 문자열)을 기반으로 일부 숫자 만 출력합니다. – QAZ

답변

0

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

편집 : 죄송합니다.

this 질문이 도움이 되겠습니까?

+0

readline()도 역시 멈 춥니 다. 콘솔 앱이 파이썬 측에서 올바르게 읽혀 져야하는 데이터를 출력하는지 확인할 수 있습니다. – QAZ

0

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

또는 실제로 어떤 이유로 stderr 대신 stdout을 쓰고 있습니까?

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

+0

고마워, 좋은 제안. 안타깝게도 콘솔 앱의 소스 코드에 액세스 할 수 없다. stderr가 아니라 stdout에 글을 확인했습니다. – QAZ

0

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

7

여기서 대화 형 응용 프로그램을 제어하려고합니다.

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

보조 프로세스의 출력을 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() 
+1

.read (1)이 작업을 차단하고 있기 때문에 Windows에서 작동하지 않습니다. –

+0

그 이유는 매 바이트마다 스크립트가 프롬프트를 사용할 수 있는지 확인한 후 새로운 바이트를 읽기 전에 새로운 명령을 쓰는 이유입니다. 스크립트를 사용해 보셨습니까? 그것은 작동합니다. – rix0rrr

+0

맞아요, 나는 그것을 한눈에 알지 못했습니다. 좋은 기대 구현을 위해 +1. –

2

Windows 끝 줄을 강제 적용하려고 했습니까? 즉

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

UPDATE :

() 난 그냥 윈도우 cmd.exe를에 솔루션을 확인했습니다 그리고 readline에 작동합니다. 그러나 그것은 Popen의 stdout에 하나의 문제가 있습니다. read blocks. 따라서 응용 프로그램이 endline없이 무언가를 반환한다면 응용 프로그램은 영원히 멈추게됩니다.

하지만 체크 아웃에 대한 주위에 일이 : http://code.activestate.com/recipes/440554/

관련 문제