Python pexpect 返回命令及其输出
我想连接到一个运行CLISH的服务器,当出现密码提示时输入密码(这个可以正常工作),然后发出一个“shell”命令让我进入bash shell(这个也可以正常工作),接着检查一个文件是否存在,如果文件缺失就打印“true”,如果存在就打印空字符串(这个也可以正常工作)。
但是,有一个地方不太对,就是我在脚本中用“pexpect.before”读取到的内容。我让pexpect等待基本的提示符,然后让我获取“before”,根据我的理解就是:“在匹配到提示符之前,你的屏幕上显示了什么?”结果我不仅得到了预期的“true”或空字符串,还得到了我用来检查文件存在性的命令。
举个例子,如果我直接通过SSH连接到机器,我会看到:
密码:而我的脚本返回的是命令和响应(问题和答案):
[ ! -f '/etc/logrotate.d/nginx' ] && echo 'true'
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 个回答
我在一个脚本中遇到了这个问题,我需要把pexpect的日志设置为sys.stdout,像下面这样:
shell = pexpect.spawn("bash")
shell.logfile = sys.stdout
我尝试了这里其他回答中建议的解决方案,但都没有成功;无论如何,传递给sendline()
的字符串都会被打印到日志中。
不过,我发现暂时禁用pexpect的日志似乎解决了这个问题:
shell.logfile = None
shell.sendline(MY_STRING)
shell.logfile = sys.stdout
有一个函数叫做 setecho
(还有一个配对的函数 getecho
),它的作用是控制发送的字符串是否会被显示出来。
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().
不过,这个功能在某些情况下似乎不太好使,所以你需要用一些其他的方法来解决这个问题。一个方法是在 bash 中关闭回显,具体可以参考 这个回答。另一个方法是使用 pexpect 的 readline
或 readlines
函数来读取输出,然后丢掉第一行,因为那一行是显示你输入的命令的。