一 paramiko模块
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,基于linux中的ssh服务
paramiko属于第三方模块,需要安装导入
pip install paramiko
1) 远程密码连接
import paramiko
#创建一个ssh对象
client=paramiko.SSHClient()
#如果之前没有连接过的ip,会出现 Are you sure you want to continue connecting (yes/no)? yes
#自动选择yes
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接服务器
client.connect(hostname='172.25.254.169',
port=22,
username='root',
password='redhat')
#执行操作
stdin,stdout,stderr=client.exec_command('hostname') #exec_command返回的为一个元组
#获取命令的执行结果
# result=stdout.read() 为2进制的对象,因此
result=stdout.read().decode('utf-8') #decode('utf-8') 对2进制的对象进行转换
print(result)
#关闭连接
client.close()
def conn(cmd,host,port=22,user='root',passwd='westos'):
#基于ssh命令用于连接远程服务器作操作:远程执行命令 上传 下载
import paramiko
#创建一个ssh对象
client=paramiko.SSHClient()
#如果之前没有连接过的ip,会出现 Are you sure you want to continue connecting (yes/no)? yes
#自动选择yes
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
#连接服务器
client.connect(hostname=host,
port=port,
username=user,
password=passwd)
except :
print('连接%s\tip失败'%(host))
else:
print('连接%s\tip成功'%(host))
#执行操作
stdin,stdout,stderr=client.exec_command(cmd) #exec_command返回的为一个元组
#获取命令的执行结果
# result=stdout.read() 为2进制的对象,因此
result=stdout.read().decode('utf-8') #decode('utf-8') 对2进制的对象进行转换
print(result)
finally:
#关闭连接
client.close()
if __name__=='__main__':
with open('ip.txt')as f:
for line in f:
line=line.strip()
host,port,user,passwd=line.split(':')
print(host.center(50,'*'))
conn('hostname',host,port,user,passwd)
from paramiko.ssh_exception import NoValidConnectionsError
def conn(cmd,host,port=22,user='root'):
#基于ssh命令用于连接远程服务器作操作:远程执行命令 上传 下载
import paramiko
#创建一个ssh对象
client=paramiko.SSHClient()
#如果之前没有连接过的ip,会出现 Are you sure you want to continue connecting (yes/no)? yes
#自动选择yes
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#创建一个私钥
private_key=paramiko.RSAKey.from_private_key_file('id_rsa.txt')
try:
#连接服务器
client.connect(hostname=host,
port=port,
username=user,
pkey=private_key)
except NoValidConnectionsError as e:
print('连接%s失败'%(host))
else:
#执行操作
stdin,stdout,stderr=client.exec_command(cmd) #exec_command返回的为一个元组
#获取命令的执行结果
# result=stdout.read() 为2进制的对象,因此
result=stdout.read().decode('utf-8') #decode('utf-8') 对2进制的对象进行转换
print(result)
finally:
#关闭连接
client.close()
host='172.25.254.169'
print(host.center(50,'*'))
conn('uname',host)
4) 基于密码的上传,下载
注意:上传,下载这里还有个默认的ftplib模块定义了FTP类
import paramiko
transport=paramiko.Transport('172.25.254.169',22)
transport.connect(username='root',password='redhat')
sftp=paramiko.SFTPClient.from_transport(transport)
#上传,下载文件 包含文件名
sftp.put('/mnt/passwd','/mnt/put_passwd')
sftp.get('/mnt/put_passwd','/home/kiosk/Desktop/get_passwd')
transport.close()
import paramiko
# 返回一个私钥对象
private_key = paramiko.RSAKey.from_private_key_file('id_rsa')
transport = paramiko.Transport(('172.25.254.169', 22))
transport.connect(username='root',pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 上传文件, 包含文件名
sftp.put('/mnt/passwd','/mnt/put_passwd')
sftp.get('/mnt/put_passwd','/home/kiosk/Desktop/get_passwd')
transport.close()
二 paramiko再次封装
先选择不同的机组,再对机组里面的主机进行操作
不同的机组文件里面,存储着不同的主机信息
import paramiko
from paramiko import SSHException
class SshRemoteHost(object):
def __init__(self, hostname, port, user, passwd, cmd):
self.hostname = hostname
self.port = port
self.user = user
self.passwd = passwd
self.cmd = cmd
def run(self):
"""默认调用的内容"""
# cmd hostname
cmd_str = self.cmd.split()[0] # cmd
if hasattr(self, 'do_' + cmd_str): # do_cmd
getattr(self, 'do_' + cmd_str)()
else:
print('不支持此命令...')
def do_cmd(self):
"""执行指定的命令"""
# 创建一个ssh对象
client = paramiko.SSHClient()
# 如果之前没有连接过的ip,会出现 Are you sure you want to continue connecting (yes/no)? yes
# 自动选择yes
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
# 连接服务器
client.connect(hostname=self.hostname,
port=self.port,
username=self.user,
password=self.passwd)
except:
print('连接%s\tip失败' % (self.hostname))
else:
print('连接%s\tip成功' % (self.hostname))
# 执行操作
cmd = ''.join(self.cmd.split()[1:])
stdin, stdout, stderr = client.exec_command(cmd) # exec_command返回的为一个元组
# 获取命令的执行结果
# result=stdout.read() 为2进制的对象,因此
result = stdout.read().decode('utf-8') # decode('utf-8') 对2进制的对象进行转换
print(result)
finally:
# 关闭连接
client.close()
def do_put(self):
print('正在上传...')
try:
transport = paramiko.Transport(self.hostname, int(self.port))
transport.connect(username=self.user, password=self.passwd)
except SSHException as e:
print('%s主机连接失败...'%(self.hostname))
else:
sftp = paramiko.SFTPClient.from_transport(transport)
newCmd = self.cmd.split()[1:]
if len(newCmd) == 2:
sftp.put(newCmd[0], newCmd[1])
print('%s文件上传到%s主机的%s文件成功!' % (newCmd[0], self.hostname, newCmd[1]))
else:
print('上传文件信息错误')
transport.close()
def do_get(self):
print('正在下载...')
try:
transport = paramiko.Transport(self.hostname, int(self.port))
transport.connect(username=self.user, password=self.passwd)
except SSHException as e:
print('连接失败...')
else:
sftp = paramiko.SFTPClient.from_transport(transport)
newCmd = self.cmd.split()[1:]
if len(newCmd) == 2:
sftp.put(newCmd[0], newCmd[1])
print('从%s主机下载的%s文件到本主机的%s文件成功!' % (self.hostname, newCmd[0], newCmd[1]))
else:
print('下载文件信息错误')
transport.close()
# 1)选择操作的主机组:web,mysql,ftp
# 主机信息的存储:将不同的主机信息存放到不同的文件中
# 2)根据选择的主机组,显示包含的主机IP/主机名
# 3)让用户确认信息,选择需要批量执行的命令:
# cmd shell命令
# put 命令
# get 命令
import os
def main():
# 1)选择操作的主机组:web,mysql,ftp
groups = [file.rstrip('.conf') for file in os.listdir('conf')]
print('主机组显示:'.center(50, '*'))
for group in groups: print('\t', group)
choiceGroup = input('请选择批量操作的主机组: ')
# 2)根据选择的主机组,显示包含的主机IP/主机名
# 打开文件/home/kiosk/PycharmProjects/python/conf
# 依次读取文件每一行
# 拿出IP
print('主机组包含的主机: '.center(50, '*'))
with open('conf/%s.conf' % (choiceGroup))as f:
for line in f:
print(line.split(':')[0])
f.seek(0, 0)
hostinfos = [line.strip() for line in f.readlines()]
# 3)让用户确认信息,选择需要批量执行的命令
print('批量执行命令中...'.center(50, '*'))
while True:
cmd = input('>>:').strip() # cmd uname
if cmd:
if cmd == 'exit' or cmd == 'quit':
print('执行结束,退出中...')
break
# 依次让该主机组的所有主机执行
for info in hostinfos:
host, port, user, passwd = info.split(':')
clientObj = SshRemoteHost(host, port, user, passwd, cmd)
clientObj.run()
if __name__ == '__main__':
main()