Python pexpect返回命令和命令的输出

时间:2013-03-04 20:59:21

标签: python ssh python-2.7 stdout pexpect

我想连接到运行CLISH的服务器,在给出密码提示时提供密码(正常工作),然后发出“shell”命令将我撞到bash shell(正常工作),然后测试是否存在如果文件丢失,则打印“true”;如果存在(工作),则打印“”(空字符串)。

什么是行不通的是我正在使用“pexpect.before”回读我的脚本。我已经要求pexpect期待基本的提示,然后根据我的理解给我'之前':“在提示匹配之前你在屏幕上看到了什么?”我不仅按预期获得了“true”或“”(空字符串),而且我还收到了我发出的命令以测试文件是否存在。

例如,如果我直接SSH到机器,我会这样做: 密码:

我的脚本返回的是命令和响应(问题和答案):

[ ! -f '/etc/logrotate.d/nginx' ] && echo 'true'

true

我只想要响应,即“真”或“”。我收到了回复,但我也得到了发出的命令。

你能看出我做错了什么吗?请帮忙!我想继续使用pexpect,因为我对SSH会话有更复杂的“期望”。

这是我的代码:

def connection(cmd):
    msg_newkey = 'Are you sure you want to continue connecting'
    p=pexpect.spawn('ssh '+user+'@'+host)
    msg = '''Super long welcome message containing your canned warning message, etc.
          myuser@'''+myhost+''''s password:'''
    i=p.expect([msg_newkey,'password:',pexpect.EOF])
    if i==0:
        print "Accepting key."
        p.sendline('yes')
        i=p.expect([msg_newkey,'password:',pexpect.EOF])
    if i==1:
        print "Supplying password"
        p.sendline(passwd)
    elif i==2:
        if "No route to host" in p.before:
            return p.before
        else:
            pass    # Add no functionality, just saying "move on"
    i=p.expect(['MYCLISHPROMPT>',pexpect.EOF])
    if i==0:
            p.sendline('shell')
    i=p.expect(['.*@.*\$',pexpect.EOF])
    if i==0:
            p.sendline(cmd)
    p.expect(['myuser@myhost:',pexpect.EOF])
    return p.before

 def look_for_file(step, filename, mytest):
    cmd = "[ ! -f '"+filename+"' ] && echo '"+mytest+"'"
    results = connection(cmd)
    print "***"+str(result)+"***"
    assert (results == '' or results == 0), "Step failed!  Error: "+results

2 个答案:

答案 0 :(得分:2)

有一个函数setecho(它的对getecho)应该控制sendline中的字符串是否会被回显。

setecho(self, state)
    This sets the terminal echo mode on or off. Note that anything the
    child sent before the echo will be lost, so you should be sure that
    your input buffer is empty before you call setecho().

但是,这显然不适用于所有情况,您需要使用一些解决方法。一种是在this answer中转换bash中的回声。另一个是使用pexpect的函数readlinereadlines来读取输出并丢弃与给定命令相呼应的第一行。

答案 1 :(得分:1)

我在脚本中遇到了这个问题,我需要将pexpect日志设置为sys.stdout,如下所示:

    shell = pexpect.spawn("bash")
    shell.logfile = sys.stdout

我尝试了其他答案中建议的解决方案但没有成功;无论如何,传递给sendline()的字符串都会打印到日志中。

但是,我发现暂时禁用pexpect日志似乎解决了这个问题:

    shell.logfile = None
    shell.sendline(MY_STRING)
    shell.logfile = sys.stdout