目录
0. 前言
1. paramiko模块安装
2. paramiko的连接
2.1 SSHClient方式连接
2.2 Transport方式连接
3. paramiko ssh连接
4. paramiko sftp示例
5. 进度条
6. 总结
0. 前言
paramiko是用python语言编写的一个模块,遵循SSH2协议,支持已加密和认证的方式,进行远程服务器的链接,利用改模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。
1. paramiko模块安装
pip install paramiko
2. 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=“密钥”)
3. 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,如果有多个命令需要操作时,要通过分号进行分割。
4. 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,那么第二个参数需要写成/路径/自己命名这个文件,否则会报错。
5. 进度条
本示例结合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符号(回到行首),加了会回到行首重新打印,在程序运行过程中,你只会看到一个进度条不断的刷新,如果不加,进度条会打满你的屏幕😄。
6. 总结
paramiko是一个比较强大的ssh连接模块,以上示例只是列出了该模块一些简单的使用方法,你可以使用threading模块加快程序并发速度;也可以使用configparser模块处理配置文件等等;后续有接触到再更新吧。
完整代码下载:paramiko_test_transport.py