我试图编写一个跨平台的工具,运行特定的命令, 期望某些输出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/ctf
为c:/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.spawn
和pexpect.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)