Vấn đề của bạn ở đây là bạn đang cố gắng kiểm soát một ứng dụng tương tác.
stdout.read()
sẽ tiếp tục đọc cho đến khi nó đến cuối luồng, tệp hoặc đường ống. Thật không may, trong trường hợp của một chương trình tương tác, đường ống chỉ đóng cửa sau đó thoát khỏi chương trình; đó là không bao giờ, nếu lệnh bạn gửi nó là bất cứ điều gì khác hơn là "quit"
.
Bạn sẽ phải hoàn nguyên để đọc đầu ra của tiến trình con theo từng dòng bằng cách sử dụng stdout.readline()
và bạn nên có cách để biết thời điểm chương trình sẵn sàng chấp nhận lệnh và khi lệnh bạn đã phát hành để chương trình kết thúc và bạn có thể cung cấp chương trình mới. Trong trường hợp của một chương trình như cmd.exe
, thậm chí readline()
sẽ không đủ vì dòng chỉ ra một lệnh mới có thể được gửi không bị chấm dứt bởi một dòng mới, do đó, sẽ phải phân tích đầu ra byte-by-byte. Dưới đây là một kịch bản mẫu chạy cmd.exe
, tìm kiếm dấu nhắc, sau đó đưa ra một dir
và sau đó một 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
Nếu thời gian là không quan trọng, và tương tác cho người dùng được không cần thiết, nó có thể được rất nhiều đơn giản chỉ để hàng loạt lên các cuộc gọi:
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()
Mã của bạn có vẻ chính xác. Console_app có hoạt động tốt khi bạn thực hiện từ giao diện điều khiển không? Nó trả về cho lệnh1 là gì? – luc
yes console_app hoạt động bình thường khi chạy trong cmd.exe Nó chỉ xuất ra một số số dựa trên đầu vào được cung cấp (và đôi khi dây) – QAZ