使用python与命令行程序交互
找了好久, 一开始的方案是 subprocess.Popen, 结果发现能收不能发, 能发不能收. 很郁闷.
发的代码:
import subprocess
import time
proc = subprocess.Popen(["a.exe"], stdin=subprocess.PIPE)
p=proc
p.stdin.write(b'asdf')
time.sleep(1)
p.stdin.write(b'2q3w')
p.stdin.write(b'zxcv')
p.communicate()
p.wait() # wait for the subprocess to exit
print("py finished")
收的代码:
import subprocess
import time
proc = subprocess.Popen(["a"], stdout=subprocess.PIPE)
p=proc
with p.stdout:
for line in iter(p.stdout.readline, b''):
print(line)
p.wait() # wait for the subprocess to exit
print("py finished")
直到有位大哥提到了Pexpect
这个库. 以及envoy
和sarge
. https://stackoverflow.com/questions/10872767/differences-between-subprocess-module-envoy-sarge-and-pexpect
- pexpect doc, on pypi, Released: Jan 22, 2020
- envoy, Released: Aug 13, 2014
- sarge doc, sarge pypi, Released: Dec 12, 2021
node的expect版本也有, 叫做node-suppose
sarge
发现sarge是比较好的解决方案:
import sys
from time import sleep
from sarge import Feeder, run, Capture
feeder = Feeder()
p = run(['a'], input=feeder, stdout=Capture(), async_=True)
sleep(1)
feeder.feed('Hello')
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
sleep(1)
feeder.feed('Yes')
sleep(1)
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
feeder.feed('Man')
sleep(1)
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
print(p.stdout.readline())
feeder.close()
p.close()