python中使用paramiko模块并实现远程连接服务器执行上传下载功能
作者:tomjoy 发布时间:2021-03-29 07:00:56
paramiko模块
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。
由于使用的是python这样的能够跨平台运行的语言,所以所有python支持的平台,如Linux, Solaris, BSD, MacOS X, Windows等,paramiko都可以支持,因此,如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,paramiko是最佳工具之一。
因此,如果需要使用SSH从一个平台连接到另外一个平台,进行一系列的操作时,paramiko是最佳工具之一。
通过ssh链接服务器并执行想要的命令,类似于XShell
ansible(远程批量管理服务器)底层源码其实就是paramiko模块实现的
安装
pip3 install paramiko
使用
前提须知:paramiko模块即支持用户名密码的方式,也支持公钥私钥的方式操作服务器
1.用户名密码的方式:
# 执行命令
import paramiko
# 创建链接对象
ssh = paramiko.SSHClient()
# 允许链接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 链接服务器
ssh.connect(hostname='服务器ip地址',port='端口号',username='用户名',password='密码')
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ip a')
"""
stdin 是用来输入额外的参数的 -y
stdout 命令的返回结果
stderr 错误的结果
"""
# 获取命令执行的结果
res = stdout.read()
print(res.decode('utf-8'))
# 关闭链接
ssh.close()
2.公钥私钥的方式
首先在windows上产生公钥私钥对
可以用openssl工具产生,也可以用Git Bash工具产生(需要安装git)
1.打开 Git Bash工具 输入命令 ssh-keygen
2.输入完命令一直按回车即可
3.在 c/user/用户名下的文件/.ssh 的目录中生成了两个密钥文件。id_rsa 为私钥,id_rsa.pub 为公钥
4.将公钥内容复制到你的linux服务器下的 /root/.ssh/authorized_keys文件中即可
复制私钥文件到项目根目录下,我这里重命名为a.txt
import paramiko
# 读取本地私钥
private_key = paramiko.RSAKey.from_private_key_file('a.txt')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='服务器ip地址', port=22, username='用户名', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')
# 获取命令结果
result = stdout.read()
print(result.decode('utf-8'))
# 关闭连接
ssh.close()
实现上传下载文件
1.用户名和密码的方式:
import paramiko
# 用户名和密码
transport = paramiko.Transport(('服务器ip地址', 22))
transport.connect(username='用户名', password='密码')
sftp = paramiko.SFTPClient.from_transport(transport)
# 上传文件
# sftp.put("a.txt", '/data/tmp.txt') # 注意上传文件到远程某个文件下 文件必须存在
# 下载文件
sftp.get('/data/tmp.txt', 'hahaha.txt') # 将远程文件下载到本地并重新命令
transport.close()
2.公钥和私钥的方式:
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('a.txt')
transport = paramiko.Transport(('服务器地址', 22))
transport.connect(username='用户名', pkey=private_key)
sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put('manage.py', '/data/test.py')
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
下面将执行命令和上传下载文件 封装到一个类里面
SSHProxy类的封装
假如我想链接服务器执行三条命令,并且上传一个文件内容
大部分都会操作几次就链接几次服务器,效率较低,代码冗余
我们想实现一个类里面包含了执行命令和上传下载文件的操作
# 类的代码无需掌握 只需要会拷贝使用即可
import paramiko
class SSHProxy(object):
# 这里的参数 你可以再加公钥私钥的形式
def __init__(self, hostname, port, username, password):
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.transport = None
def open(self): # 给对象赋值一个上传下载文件对象连接
self.transport = paramiko.Transport((self.hostname, self.port))
self.transport.connect(username=self.username, password=self.password)
def command(self, cmd): # 正常执行命令的连接 至此对象内容就既有执行命令的连接又有上传下载链接
ssh = paramiko.SSHClient()
ssh._transport = self.transport
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
return result
def upload(self, local_path, remote_path):
sftp = paramiko.SFTPClient.from_transport(self.transport)
sftp.put(local_path, remote_path)
sftp.close()
def close(self):
self.transport.close()
def __enter__(self): # 对象执行with上下文会自动触发
self.open()
return self # 这里发挥上面with语法内的as后面拿到的就是什么
def __exit__(self, exc_type, exc_val, exc_tb): # with执行结束自动触发
self.close()
使用流程
"""
上述的封装操作在使用的使用 必须按照下面的顺序
obj = SSHProxy(...)
obj.open() # 产生的对象必须要先执行open方法
obj.command('ls /')
obj.command('cat /data/tmp.txt')
obj.upload(...)
obj.upload(...)
obj.close()
利用文件操作的特性
f = open()
f.close()
嫌上述操作麻烦 利用with上下文做处理了
with open() as f:
pass
as后面的值由__enter__方法返回值决定 返回什么就是什么
# 一旦对象被执行with会自动触发对象内部的__enter__方法 with结束之后还会自动触发__exit__方法
obj = SSHProxy(1,2,3,4)
with obj as f:
pass
封装之后按照下面的方式使用即可
with SSHProxy(....) as obj:
obj.command()
obj.command()
obj.upload()
obj.upload()
obj.command()
"""
拓展: __enter__ 和 __exit__ 的使用
class Foo(object):
def __enter__(self):
print('他进来了')
return 123
def __exit__(self, exc_type, exc_val, exc_tb):
print('他就这么出去了')
obj = Foo()
with obj as f:
print(f)
"""
执行结果:
他进来了
123
他就这么出去了
"""
总结:as后面的值由 __enter__ 方法返回值决定 返回什么就是什么,
一旦对象被执行with会自动触发对象内部的 __enter__ 方法 with结束之后还会自动触发 __exit__ 方法
面试题
# 面试题"""
请在Context类中添加代码完成该类的实现(意思是怎么样修改才能实现以下代码并不会报错)
"""
class Context:
pass
with Context() as ctx:
ctx.do_something()
# 答案
class Context:
def __enter__(self):
return self
def __exit__(self,*args,**kwargs):
pass
def do_something(self):
pass
来源:https://www.cnblogs.com/guapitomjoy/p/12382084.html
猜你喜欢
- 问题背景a=[1,4,2,1,5,6,9,0]#删除列表中的元素,其所在的位置为[1,3,7]del_index=[1,3,7]tmp=[i
- 你是否有时想知道什么人访问你的站点,什么时间,IP地址等。下面我就这个问题向大家来阐述一下。这个例子使用文本文件来写入用户的信息创建一个lo
- 本文实例讲述了python实现生成Word、docx文件的方法。分享给大家供大家参考,具体如下:http://python-docx.rea
- 引言提到 numpy 的数组操作,我们就不得不说到 np.concatenate() 函数,concatenate 一词在英文中是级联的意思
- 前言 在我们学习C语言时,我们学了
- 缘起最近复习设计模式拜读谭勇德的<<设计模式就该这样学>>该书以java语言演绎了常见设计模式本系列笔记拟采用gol
- 1.计算机语言的基本概念 计算机语言(Computer Language) 指用于人与计算机之间的通信。2.解释型和编译型语言的区别 编译型
- 关于文件下载官网都有提供最新版本的推荐自行下载,如果不介意旧版本的,可以留言我可以分享我是用的版本~Anaconda安装打开下载的.exe文
- 生产系统随着业务增长总会经历一个业务量由小变大的过程,可扩展性是考量数据库系统高可用性的一个重要指标;在单表/数据库数据量过大,更新量不断飙
- 学习vue和nodejs的过程当中,涉及到了axios,今天为了测试,写了get和post两个方法来跟node服务端交互,结果因为heade
- 使用 WinHttpRequest 伪造 HTTP 头信息,伪造 Referer 等信息。由于微软封锁了 XmlHttp 对象,所以无法伪造
- 以下效率,是奔腾 dual1.6G HZ,1G内存电脑,ie6.0下toggle()与slideToggle("fast"
- 构建运动模糊模型现假定相机不动,图像f(x,y)在图像面上移动并且图像f(x,y)除移动外不随时间变化。令x0(t)和y0(t)分别代表位移
- 本文实例讲述了JS实现仿Windows经典风格的选项卡Tab切换代码。分享给大家供大家参考,具体如下:这款仿Windows风格的选项卡,带有
- 字体设计是人类商业活动的需求,它随着时代和科学技术的进步而不断地变化着。被广泛应用于网络生活的各个方面。现代字体设计在电脑技术的应用中已经深
- 但有时候,需要当某事件触发时,我们先做一些操作,然后再跳转,这时,就要用JAVASCRIPT来实现这一跳转功能。 下面是具体的做法: 一:跳
- 引言我们经常听到"因为GIL的存在,python的多线程不能利用多核CPU",现在我们暂且不提GIL,python能不能
- 需求:启动程序后,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒可随时
- 有时候要通过asp代码在数据库中创建表和列,下面的就是这些操作的函数。1.检测表是否存在tbName 检测的表的名称dbTp 数据库的类型1
- 一图胜“十”言:SQL Server 数据库总结 一个大概的总结 经过一段时间的学习,也对数据库有了一些认识。 数据库基本是由表,关系,操作