我想寫一個運行特定命令的跨平臺工具,預計某些輸出驗證,併發送某些輸出(如用戶名/密碼)進行身份驗證。Windows替代pexpect
在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
documentation:
pexpect.spawn
和pexpect.run()
不可用在Windows ,因爲它們依賴於Unix僞終端(ptys)。跨平臺代碼不得使用這些代碼。
這使我對我的搜索Windows平臺上類似。我曾嘗試流行winpexpect
項目here,甚至更近(叉)here版本,但無論這些項目似乎工作。我使用的方法:
self.process = winpexpect.winspawn('c:/ctf.exe', env={'HOME':expanduser('~')}, timeout=5)
只能眼睜睜地看着命令提示符什麼也不做(這好像它被困在winspawn
方法內)。我想知道還有什麼其他方法可以編寫一個Python腳本來與命令行進行交互,以達到與我在Unix中一樣的效果?如果一個合適的Windows版本pexpect
腳本不存在,我可以使用其他方法來解決這個問題?
我懷疑這是在Windows上導致您的問題的密碼提示。將密碼發送到'PLINK'(ssh)命令時遇到了很多麻煩,最後放棄了。我個人使用'subprocess.Popen'和行掃描(手動代碼)來做到這一點。至少你不能將用戶/密碼傳遞給你的命令嗎? –
winpexpect使用管道作爲標準手柄。在這種情況下,大多數命令行程序都會切換到完全緩衝標準輸出,因此只有當緩衝區填滿和刷新時纔會看到輸出。通常緩衝區是4 KiB。 – eryksun
如果您連接到與子進程相同的控制檯,則可以使用Windows控制檯API直接寫入其輸入緩衝區並從屏幕緩衝區中讀取。您甚至可以創建一個新的空白屏幕緩衝區,它可以暫時設置爲活動屏幕緩衝區或由文件描述符引用,並以'stdout'的形式傳遞給'subprocess.Popen'。 – eryksun