2017-04-12 17 views
1

일반적인 문제는 pexpect를 사용하여 sudo 권한이 필요한 스크립트를 호출하고 싶지만 암호를 한 번만 입력하고 싶지는 않다는 것입니다.pexpect에서 expect()와 interact()를 동시에 사용하기

내 계획은 pdopect를 사용하여 sudo 권한으로 bash 세션을 생성하고 거기에서 스크립트를 호출하는 것입니다. 기본적으로 저는 항상 세션을 바쁘게하고 싶습니다. 한 스크립트가 멈 추면 다른 스크립트를 시작하고 싶습니다. 그러나 스크립트가 실행되는 동안 사용자가 제어 할 수 있어야합니다. 의미 :

스크립트는 expect ("root @") 다음에 호출되어야하므로 세션이 유휴 상태 일 때마다 다른 스크립트가 시작됩니다. 스크립트가 interact()를 실행하는 동안 사용자가 원하는 입력을 제어 할 수 있습니다.

제 아이디어는이 문제를 해결하기 위해 다른 스레드를 사용하는 것이 었습니다. 나는이 스크립트를 호출 할 때

import pexpect 
import threading 

class BashInteractThread(threading.Thread): 
    def __init__(self, process): 
     threading.Thread.__init__(self) 
     self.pproc = process 

    def run(self): 
     self.pproc.interact() 


s = pexpect.spawn("/bin/bash", ['-i', '-c', "sudo bash"]) 

it = BashInteractThread(s) 
it.start() 

s.expect("[email protected]") 
s.sendline("cd ~") 
while(s.isalive()): 
    pass 


s.close() 

, 그것은 나에게 출력을 제공하지 않지만, 프로세스가 시작된 것 같습니다 : (개념 증명에 대한) 내 코드는 다음과 같습니다. 여전히 CTRL-C 나 CTRL-D로 프로세스를 죽일 수는 없습니다. 프로세스를 개별적으로 종료해야합니다. 내가 기대하는 행동은 암호를 입력하라는 메시지를받는 것이고 그 후에는 자동으로 디렉토리를 홈 디렉토리로 변경해야합니다. 정확히 작동하지 않는 이유를 정확히 알지 못하지만 출력이 interact() 또는 expect()로만 전달됩니다.

누구든지 해결 방법에 대한 아이디어가 있습니까? 미리 감사드립니다.

답변

1

interact(output_filter=func)을 이용할 수 있습니다. 방금 간단한 예제 (코딩 스타일 없음!)를 작성했습니다. 그것이하는 일은 Bash 셸을 생성하고 사용자가 상호 작용할 수 있도록 반복적으로 Python을 호출하는 것입니다. 트랩을 종료하려면 마법 단어 LET ME OUT을 입력 (또는 인쇄)하면됩니다.

expect()interact() 이후에는 더 이상 작동하지 않으므로 수동으로 패턴 일치 작업을 수행해야합니다.

코드 :

[STEP 101] # cat interact_with_filter.py 
import pexpect, re 

def output_filter(s): 
    global proc, bash_prompt, filter_buf, filter_buf_size, let_me_out 

    filter_buf += s 
    filter_buf = filter_buf[-filter_buf_size:] 

    if "LET ME OUT" in filter_buf: 
     let_me_out = True 

    if bash_prompt.search(filter_buf): 
     if let_me_out: 
      proc.sendline('exit') 
      proc.expect(pexpect.EOF) 
      proc.wait() 
     else: 
      proc.sendline('python') 

    return s 

filter_buf = '' 
filter_buf_size = 256 
let_me_out = False 
bash_prompt = re.compile('bash-[.0-9]+[$#] $') 

proc = pexpect.spawn('bash --noprofile --norc') 
proc.interact(output_filter=output_filter) 

print "BYE" 
[STEP 102] # 

이의 그것을 시도하자

[STEP 102] # python interact_with_filter.py 
bash-4.4# python 
Python 2.7.9 (default, Jun 29 2016, 13:08:31) 
[GCC 4.9.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> exit()   <---- user input 
bash-4.4# python 
Python 2.7.9 (default, Jun 29 2016, 13:08:31) 
[GCC 4.9.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> exit()   <---- user input 
bash-4.4# python 
Python 2.7.9 (default, Jun 29 2016, 13:08:31) 
[GCC 4.9.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> LET ME OUT  <---- user input 
    File "<stdin>", line 1 
    LET ME OUT 
     ^
SyntaxError: invalid syntax 
>>> exit()   <---- user input 
bash-4.4# BYE 
[STEP 103] # 
+0

Gread 아이디어를! 고마워,이게 효과가 있어야 해! – brandenb