簡介:
Paramiko是基於Python(2.7,3.4+)版本實現和封裝了SSHv2協議,底層是用cryptography實現,我們如果希望遠程登錄主機或者遠程下載或者上傳文件到遠程主機都可以使用該庫實現。Paramiko屬於第三方python庫,需要我們使用pip進行安裝,如果是離線需要在有網絡的環境下載好whl文件,再到對應的離線環境進行安裝。
主要功能:
類似於SSH協議,Paramiko主要分為SSHClient和SFTPClient,前者主要對遠程主機進行操作,輸入命令對遠程主機進行控制,后者主要實現了從遠程主機上上傳下載文件,除此之外還有很多實用的方法,本文主要是自己在工作中經常使用的方法進行封裝,更多更全面的介紹請參考paramiko的api文檔https://www.paramiko.org/
import paramiko class SSHConnection: # 初始化連接創建Transport通道 def __init__(self, host, user, pwd): self.host = host self.port = 22 self.user = user self.pwd = pwd self.__transport = paramiko.Transport((self.host, self.port)) self.__transport.connect(username=self.user, password=self.pwd) self.sftp = paramiko.SFTPClient.from_transport(self.__transport) # 關閉通道 def close(self): self.sftp.close() self.__transport.close() # 上傳文件到遠程主機 def upload(self, local_path, remote_path): self.sftp.put(local_path, remote_path) # 從遠程主機下載文件到本地 def download(self, local_path, remote_path): self.sftp.get(remote_path, local_path) # 在遠程主機上創建目錄 def mkdir(self, target_path, mode='0777'): self.sftp.mkdir(target_path, mode) # 刪除遠程主機上的目錄 def rmdir(self, target_path): self.sftp.rmdir(target_path) # 查看目錄下文件以及子目錄(如果需要更加細粒度的文件信息建議使用listdir_attr) def listdir(self, target_path): return self.sftp.listdir(target_path) # 刪除文件 def remove(self, target_path): self.sftp.remove(target_path) # 查看目錄下文件以及子目錄的詳細信息(包含內容和參考os.stat返回一個FSTPAttributes對象,對象的具體屬性請用__dict__查看) def listdirattr(self, target_path): try: list = self.sftp.listdir_attr(target_path) except BaseException as e: print(e) list = [] return list # 獲取文件詳情 def stat(self, remote_path): return self.sftp.stat(remote_path) # SSHClient輸入命令遠程操作主機 def cmd(self, command): ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy) # 設置以什么方式連接遠程客戶端,這里配置自動協商 ssh._transport = self.__transport stdin, stdout, stderr = ssh.exec_command(command) # 遠程執行命令,結果會返回標准輸入、標准輸出、標准錯誤輸出 result = stdout.read() print(result) return result
具體使用舉例:
from paramikotools import SSHConnection import os import time import datetime from cmdline import parse_args from util_log import Logging ssh = None logging = Logging().get_logger() #遞歸遍歷遠程目錄下的所有文件 def gci(remote_path,pathlist): for f in ssh.listdirattr(remote_path): if (str(f.longname).split(" ")[0].startswith('d')): gci(os.path.join(remote_path,f.filename),pathlist) else: pathlist.append(os.path.join(remote_path,f.filename)) return pathlist if __name__ == '__main__': #接收參數 args = parse_args() #初始化ssh ssh = SSHConnection(host=args.srchost,user=args.srcuser,pwd=args.srcpasswd) while True: try: #創建本地接收文件目錄(按天創建目錄) datedir = os.path.join(args.dstpath,datetime.datetime.now().strftime('%Y%m%d')) #創建子目錄之前保證父級目錄創建否則拋出異常 os.mkdir(args.dstpath) os.mkdir(datedir) except BaseException as e: pass beforedict = dict() afterdict = dict() pathlist = [] #獲取所有文件名以及每個文件的當前大小 for i in gci(args.srcpath,pathlist): beforedict.setdefault(i,ssh.stat(i).st_size) #隔interval秒獲取每個文件名以及當前大小 time.sleep(int(args.interval)) for i in gci(args.srcpath,pathlist): afterdict.setdefault(i,ssh.stat(i).st_size) #對比時間前后文件大小如果一致認為文件已經生成完成,將文件下載到本地 for i in beforedict.keys(): if beforedict.get(i) == afterdict.get(i): try: ssh.download(os.path.join(datedir,os.path.basename(i)),i) logging.info('File '+i+' download completed') ssh.remove(i) logging.info('File '+i+' deleted') except BaseException as e: logging.error('File '+i+' download failed') logging.error(e) logging.error('File '+i+' delete failed') ssh.close()
參考:https://blog.csdn.net/qq_24674131/article/details/95618304