2017-04-12 65 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