2016-08-16 6 views
2

특정 명령을 실행하는 교차 플랫폼 도구를 작성하려고합니다. 은 확인을 위해 특정 출력을 기대하고 인증을 위해 특정 출력 (예 : 사용자 이름/암호)을 보냅니다.pexpect에 대한 Windows 대안

유닉스에서 pexpect 라이브러리 (pip install pexpect 통해)를 사용하는 Python 도구를 프로그래밍하는 데 성공했습니다. 이 코드는 완벽하게 작동하며 정확하게하려고합니다. 나는 아래 컨셉 증명에 대한 내 코드의 작은 발췌를 제공 한 :

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)) 

내가 (c:/ctf.exe/usr/bin/ctf 변경) Windows에서 동일한 소스를 실행 시도하고 나는 오류 메시지가 나타납니다

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' 

는에 따르면,이 pexpectdocumentation :

pexpect.spawnpexpect.run() Windows에서 사용할 수 없습니다 , 그들은 유닉스 pseudoterminals (ptys)에 의존하기 때문에. 크로스 플랫폼 코드는이를 사용하지 않아야합니다.

그 이유는 나를 동등한 Windows 검색에 이끌었습니다. winpexpect 프로젝트 here과 심지어 가장 최근의 (분기 된) 버전 here을 시도했지만이 프로젝트 중 어느 것도 작동하지 않습니다.

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

은 (는 winspawn 방법 안에 갇혀있는 것처럼 보인다) 앉아서 명령 프롬프트가 아무것도하지 않고 볼 : 나는 방법을 사용합니다. 파이썬 스크립트를 프로그래밍하여 명령 행과 상호 작용하여 내가 유닉스에서 할 수 있었던 것과 같은 효과를 얻을 수 있다는 것을 다른 무엇이 의미하는지 궁금했다. 적합한 Windows 버전 pexpect 스크립트가 존재하지 않는다면, 다른 방법으로이 문제를 해결할 수 있습니까?

+0

나는이 문제가 Windows에서 문제가되는 암호 프롬프트라고 생각합니다. 나는'PLINK' (ssh) 명령에 암호를 보내는 데 많은 어려움을 겪었고 결국 그것을 포기했습니다. 개인적으로'subprocess.Popen'을 사용하여 라인 스캐닝 (수동 코드)을하면됩니다. 적어도 사용자의 명령에 사용자/암호를 전달할 수 없습니까? –

+0

winpexpect는 표준 핸들에 파이프를 사용합니다. 이 경우 대부분의 명령 줄 프로그램은 버퍼링이 완료된 stdout으로 전환되므로 버퍼가 가득 차서 플러시 될 때만 출력이 표시됩니다. 일반적으로 버퍼는 4KB입니다. – eryksun

+0

자식 프로세스와 동일한 콘솔에 연결되어있는 경우 Windows 콘솔 API를 사용하여 입력 버퍼에 직접 쓰고 화면 버퍼에서 읽을 수 있습니다. 활성 화면 버퍼로 일시적으로 설정되거나 파일 디스크립터에 의해 참조되고'stdout'으로'subprocess.Popen'에 전달 될 수있는 새로운 빈 화면 버퍼를 생성 할 수도 있습니다. – eryksun

답변

1

pexpect.spawn 대신 windowspexpect.popen_spawn.PopenSpawn을 사용할 수 있습니다.

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