首先说几个问题:
-
同样百度了博客等渠道,很多方式基于paramiko库,但是这种库我在使用的过程中,出现连接被拒绝或者无效地址等问题。
-
还有基于ssh2的方式,这种方式是基于免密配置的,不需要输入密码就能连接的,但是通常情况下是需要与shell交互输入yes与密码才能连接的。
上述两个问题是我在实例过程中出现的,可能有人成功了,有人与我有一样的疑惑。疑惑怎么样才能与shell进行交互,自动输入密码进行连接。
linux 有expect脚本,能够与shell进行交互,在使用pexpect库之前,用起来还是可以的,但是使用了pexpect库之后发现这个脚本交互语法很麻烦。
下面给出本人写的一个远程连接类,能够连接远程主机(端口是默认的),能够执行远程命令并返回当前命令所造成的输出。参考:感谢大佬原文
#!/usr/bin/python
# coding=utf-8
#
'''
登录ssh并执行命令,端口为默认ssh端口
'''
try:
import pexpect
except:
import os
import sys
if sys.version_info < (3, 0):
os.system("pip2 install pexpect")
else:
print "using python 2.X."
import pexpect
import re
PROMPT = ['#', '>>>', '>', '\$']
class SSHOpreator:
def __init__(self, user, host, pwd):
self.user = user
self.host = host
self.pwd = pwd
self.ssh = None
def send_command(self, cmd):
# 执行命令,并返回结果
self.ssh.sendline(cmd) # 传递命令
self.ssh.buffer=""
self.ssh.expect(PROMPT) # 期望获得的命令提示符
return self.ssh.before # 获取远程打印命令
def close(self):
self.ssh.close()
def connect(self):
ssh_newkey = "Are you sure you want to continue connecting"
constr = "ssh "+self.user+"@"+self.host
self.ssh = pexpect.spawn(constr)
ret = self.ssh.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
return False, '[%s@%s] Error Connecting' % (self.user, self.host)
if ret == 1:
self.ssh.sendline("yes") # 发送YES
ret = self.ssh.expect(
[pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
return False, '[%s@%s] Error Connecting' % (self.user, self.host)
self.ssh.sendline(self.pwd)
self.ssh.expect(PROMPT)
return True, '[%s@%s] success Connecting' % (self.user, self.host)
if __name__ == "__main__":
ssh = SSHOprator(user='root', host='127.0.0.1', pwd='zzllzmm0')
ret, msg=ssh.connect()
if not ret:
print msg
exit(0)
cmd = "cd /home/zhangze"
result = ssh.send_command(cmd)
cmd = "ll"
result = ssh.send_command(cmd)
result=re.sub('[\s]+',' ',result)
i=0
print result
补充:在实际项目中又遇见一个问题,那就是主机与远程机采用的python环境编码格式不一样,倒是执行远程命令时会抛出一个waring一场,但是此时远程命令是执行了的,还是会抛出异常。查看源码发现是一个waring,然是程序不继续执行了。
此时,应先发送 export PYHTONENCODING=utf-8 的命令,胡总和其他,与本机PYTHONENCODING同步,然后在执行命令则会成功。