2017-04-12 59 views
1

一般問題是,我想用pexpect調用需要sudo權限的腳本,但我並不總是想輸入密碼(只有一次)。在expect中同時使用expect()和interact()

我的計劃是使用pexpect與sudo權限產生bash會話並從那裏調用腳本。基本上,我總是希望保持會話繁忙,每當一個腳本停止時,我想開始另一個腳本。但是在腳本運行時,我希望用戶能夠控制。含義:

腳本應該在expect之後調用(「root @」),所以無論何時會話空閒,它都會啓動另一個腳本。腳本運行時,交互()使用戶可以控制可能的輸入。

我的想法是使用不同的線程來解決這個問題。我(對概念的證明)的代碼如下所示:

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