您的位置:首页 > 编程语言 > Python开发

python模块paramiko与进度条

2020-07-20 15:34 141 查看

前言

   paramiko是用python语言编写的一个模块,遵循SSH2协议,支持已加密和认证的方式,进行远程服务器的链接,利用改模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。

一、paramiko模块安装

pip install paramiko

二、paramiko的连接

   使用paramiko模块有两种连接方式,一种是通过paramiko.SSHClient()函数,另一种是通过paramiko.Transport()函数。

2.1 SSHClient方式连接
import paramiko as pk

ssh = pk.SSHClient()
ssh.set_missing_host_key_policy(pk.AutoPolicy()) # 允许连接不在know_hosts文件中的主机
ssh.connect(“ip地址”, 22, “用户名”, “密码”)
2.2 Transport方式连接
import paramiko as pk

t = pk.Transport((“主机”, “端口”))
t.connect(username=“用户名”, password=“密码”)

   如果连接远程主机需要提供密钥,上面第二行可以改成:

t.connect(username=“用户名”, password=“密码”, hostkey=“密钥”)

三、paramiko ssh连接

   以下是一个简单的通过paramiko模块定义的ssh连接并执行命令的函数:

import paramiko as pk

def ssh_exec_cmd(ip, port, username, passwd, cmd):
try:
s = pk.SSHClient()
s.set_missing_host_key_policy(pk.AutoPolicy())
s.connect(ip, port, username, passwd, timeout=5)
stdin, stout, stderr = s.exec_command(cmd)
print(stdout.read())
s.close()
except:
print(“%s” % ip)

ssh2(“192.168.1.3”, 22, “root”, “123456”, “ifconfig”)

   stdin.write部分用于交互情况,通过该命令可以执行交互(这里指的交互是后面cmd需要的执行程序可能出现的情况,比如删除某个文件提示你输入字母确认的时候)。
   stdout标准输出,在内容较少时,可以通过read方法读取所有的输出;内容过多时可以通过readline或readlines处理。
   在调用过程中需要注意的是,ip,username,passwd均属于字符串类型,需要加上引号。后面执行的cmd,如果有多个命令需要操作时,要通过分号进行分割。

四、paramiko sftp示例

   下载文件示例:

import paramiko as pk

s = pk.Transport((“ip”, port))
s.connect(username=“root”, passwd=“123456”)
sftp = pk.SFTPClient.from_transport(s)
# 上传则改为put方法即可
sftp.get(“远程主机文件路径”, “本地存放文件路径”)
sftp.close()

   如果需要下载或者上传目录,只能遍历出所有文件路径,然后循环上传或者下载,不论上传下载,get和put方法第二个参数需要写到文件名,比如远端文件路径为/root/test.py,那么第二个参数需要写成/路径/自己命名这个文件,否则会报错。

五、进度条

   本示例结合sftp上传和进度条展示一个简单的功能,代码如下:

import sys
import time
import paramiko as pk

class SftpTest(object):
def __init__(self, ip, port,  username, password, local_path, remote_path):
self.ip = ip
self.port = port
self.username = username
self.password = password
self.local_path = local_path
self.remote_path = remote_path

def translate_byte(self, B):
B = float(B)
KB = float(1024)
MB = float(KB ** 2)
GB = float(MB ** 2)
TB = float(GB ** 2)
if B < KB:
return '{} {}'.format(B, 'bytes' if B > 1 else byte)
elif KB < B < MB:
return '{:.2f} KB'.format(B / KB)
elif MB < B < GB:
return '{:.2f} MB'.format(B / MB)
elif GB < B < TB:
return '{:.2f} GB'.format(B / GB)
else:
return '{:.2f} TB'.format(B / TB)

def timer(func):
def inside(self):
t1 = time.time()
func(self)
t2 = time.time()
print('task time:{:.2f}s'.format(t2 - t1))
return inside

def call_back(self, curr=100, total=100):
bar_length = 100
percents = '\033[32;1m%s\033[0m' % round(float(curr) * 100 / float(total), 2)
filled = int(bar_length * curr / float(total))
bar = '\033[32;1m%s\033[0m' % '=' * filled + '-' * (bar_length - filled)
print('translating: [{}] {}% already complete: {}, total: {}\r'.format(bar, percents, self.translate_byte(curr), self.translate_byte(total)), end='')

@timer
def ftpupload(self):
transport = pk.Transport(self.ip, sself.port)
try:
transport.connect(username=self.username, password=self.password)
sftp = pk.SFTPClient.from_transport(transport)
print('Begin translating...')
sftp.put(self.local_path, self.remote_path, callback=self.call_back)
print('\nFinish translating...')
except Exception as e:
print(str(e))
finally:
transport.close()

if __name__ = '__main__':
local_path = sys.argv[1]
remote_path = sys.argv[2]
ftp_obj = SftpTest('8.0.187.145', 22, 'root', '123456', local_path, remote_path)
ftp_obj.ftpupload()

   sftp的get和put方法提供一个callback参数用来执行回调函数,示例在回调中绘制了进度条。关于进度条,总的来说就是先打印出一个内容,根据传输内容,更新打印的内容即可,需要注意的是打印进度条的时候的\r符号(回到行首),加了会回到行首重新打印,在程序运行过程中,你只会看到一个进度条不断的刷新,如果不加,进度条会打满你的屏幕😄。

六、总结

   paramiko是一个比较强大的ssh连接模块,以上示例只是列出了该模块一些简单的使用方法,你可以使用threading模块加快程序并发速度;也可以使用configparser模块处理配置文件等等;后续有接触到再更新吧。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: