Windows替代pexpect

我试图编写一个跨平台的工具,运行特定的命令, 期望某些输出validation,并发送特定的输出(如用户名/密码)进行身份validation。

在Unix上,我成功地编写了一个使用pexpect库的Python工具(通过pip install pexpect )。 此代码完美工作,正是我想要做的。 我在下面提供了我的代码的一小段摘录:

 self.process = pexpect.spawn('/usr/bin/ctf', env={'HOME':expanduser('~')}, timeout=5) self.process.expect(self.PROMPT) self.process.sendline('connect to %s' % server) sw = self.process.expect(['ERROR', 'Username:', 'Connected to (.*) as (.*)']) if sw == 0: pass elif sw == 1: asked_for_pw = self.process.expect([pexpect.TIMEOUT, 'Password:']) if not asked_for_pw: self.process.sendline(user) self.process.expect('Password:') self.process.sendline(passwd) success = self.process.expect(['Password:', self.PROMPT]) if not success: self.process.close() raise CTFError('Invalid password') elif sw == 2: self.server = self.process.match.groups()[0] self.user = self.process.match.groups()[1].strip() else: info('Could not match any strings, trying to get server and user') self.server = self.process.match.groups()[0] self.user = self.process.match.groups()[1].strip() info('Connected to %s as %s' % (self.server, self.user)) 

我试图在Windows上运行相同的源代码(将/usr/bin/ctfc:/ctf.exe ),并收到错误消息:

 Traceback (most recent call last): File ".git/hooks/commit-msg", line 49, in <module> with pyctf.CTFClient() as c: File "C:\git-hooktest\.git\hooks\pyctf.py", line 49, in __init__ self.process = pexpect.spawn('c:/ctf.exe', env={'HOME':expanduser('~')}, timeout=5) AttributeError: 'module' object has no attribute 'spawn' 

根据pexpect 文件 :

pexpect.spawnpexpect.run()在Windows上不可用,因为它们依赖于Unix伪pexpect.run() pexpect.spawn )。 跨平台代码不能使用这些。

这导致我寻找一个Windows的等价物。 我已经在这里尝试了stream行的winpexpect项目,甚至更近一些(分叉)的版本,但这些项目似乎都没有工作。 我使用的方法是:

 self.process = winpexpect.winspawn('c:/ctf.exe', env={'HOME':expanduser('~')}, timeout=5) 

只能坐下来看命令提示符什么也不做(看起来好像被困在winspawn方法里面)。 我想知道还有什么其他的手段可以去编程一个Python脚本来与命令行进行交互,以达到和我在Unix上一样的效果? 如果一个合适的Windows版本的pexpect脚本不存在,还可以使用其他方法来解决这个问题。

您可以使用pexpect.popen_spawn.PopenSpawn for windows来代替使用pexpect.spawn

 child = pexpect.popen_spawn.PopenSpawn('cmd', timeout=1) child.send('ipconfig') child.expect('Wireless', timeout=None)