paramiko是用python語言寫的一個模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的連接。
- 創建paramiko_client - 基於用戶用密碼
- 存在寫死的代碼 理解明白即可,可自定義在相應的配置文件中
- 其中包括創建sftp連接用於本地與服務器文件的上傳與下載
- 配置文件在下方
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/23 9:10
# @Author : ****
import paramiko
import ConfigParser
class PKClient(object):
def __init__(self, config_str, com_str=''):
"""
:param config_str: 配置文件
:param com_str: 遠程服務器運行的指令
"""
self.config = ConfigParser.ConfigParser()
self.config.read(config_str)
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client_status = 0
self.sftp_client = None
self.com_str = com_str
def get_sftp_client(self):
"""
創建sftp連接
:return:
"""
if self.client_status == 0:
self.connect()
if not self.sftp_client:
self.sftp_client = paramiko.SFTPClient.from_transport(self.client.get_transport())
return self.sftp_client
def run_cmd(self):
"""
連接服務器後進行命令操作
:return:
"""
stdin, stdout, stderr = self.client.exec_command(self.com_str)
for item in stdout:
print(item)
self.client_status = 1
def connect(self):
"""
連接遠程服務器
連接異常關閉連接
:return:
"""
try:
self.client.connect(hostname=self.config.get('ssh', 'hostname'), port=self.config.getint('ssh', 'port'),
username=self.config.get('ssh', 'username'),
password=self.config.get('ssh', 'password'),
timeout=self.config.getfloat('ssh', 'timeout'))
except Exception, e:
print(e)
try:
self.client.close()
except:
pass
self.run_cmd()
if __name__ == '__main__':
PKClient(r'D:\Python2.7\untitled\text-paramiko\config.ini', 'date').get_sftp_client()
- 此處爲 config.ini 配置文件的內容
[ssh]
hostname=xxx.xxx.xxx.xxx
port=端口號
username=用戶名
password=密碼
timeout=1
- 文件的上傳
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/23 13:04
# @Author : ****
from paramiko_client import PKClient
client = PKClient('config.ini')
# client.connect()
sftp_client = client.get_sftp_client()
def put_callback(size1, size2): # 回調函數,用於顯示(上傳文件)本地與服務器端的文件大小,可優化爲md5值進行比較
print(size1, size2)
# (本地,服務器端,回調函數(可省略))
sftp_client.put(r'D:\Python2.7\untitled\text-paramiko\config.ini', '/home/zyy/config.ini', put_callback)
- 文件的下載
#!/user/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/11/21 18:06
# @Author : ****
import os
from paramiko_client import PKClient
import ConfigParser
class BaseFileInfo:
def __init__(self, name=None, seq=None):
"""
:param name: 文件名
:param seq: 文件版本號
conf.get('total', 'req') 爲大版本的版本號
"""
self.name = name
self.seq = seq
self.client = PKClient('config.ini', '')
self.sftp_client = self.client.get_sftp_client()
self.conf = ConfigParser.ConfigParser()
self.conf.read('res.txt')
self.total_seq = self.conf.get('total', 'req')
self.ori_total_seq = 0
self.file_map = {} # 存放 [] 下的每一項文件的名稱及版本號
@staticmethod
def get_callback(size1, size2):
"""
:param size2: 服務器端文件大小
:param size3: 本地文件大小
:return:
"""
print(size1, size2)
def run(self):
"""
下載服務器端文件版本的序列號記錄文件 res_des.txt
conf.sections() 這個東西爲 res_des.txt文件中的[file] 每一項[]內的內容
:return:
"""
self.client.sftp_client.get('/home/zyy/client_res/res_des.txt', r'D:\Python2.7\untitled\text-paramiko\res.txt', self.get_callback)
if self.total_seq != self.ori_total_seq: # 比較本地與服務器端版本號是否一致
sectons = self.conf.sections() # res.txt 中的 []
for secton in sectons:
if secton == 'files':
for conf in self.conf.items(secton): # ('t1.txt', '1') 爲 []下的每一個文件名稱對應的版本號
name = conf[0]
seq = conf[1]
if name in self.file_map: # 文件名稱在,版本號不同進行文件更新
file = self.file_map[name]
if file.seq != seq:
self.sftp_client.get('/home/zyy/client_res/' + name, r'D:\Python2.7\untitled\text-paramiko' + os.sep + name)
else:
self.sftp_client.get('/home/zyy/client_res/' + name, r'D:\Python2.7\untitled\text-paramiko' + os.sep + name)
info = BaseFileInfo(name, seq) # 文件名稱及版本號
self.file_map[name] = info
if __name__ == '__main__':
BaseFileInfo().run()