• pysftp-tools


    import pysftp
    import paramiko
    import os
    import unittest
    import json
    import warnings
    warnings.filterwarnings("ignore")
    
    class SftpUtils(object):
        """
        cmd: execute shell command on  remote  linux server.
        exist_file : if remote path exists on remote return True ,else return False.
        exist_dir : if remote path exists on remote return True ,else return False.
        is_dir: if remote path is dir return True ,else return False.
        is_file : if remote path is file return True ,else return False.
        remove:  remove the remote file on remote linux .
        rm:  remove dir and all files/dir under remote dir and dir it self.
        mkdir: mkdir dir on remote linux but it parent dir must exists ,if it already exist delete remote dir exists first and mkdir remote dir .
        makedirs: mkdir the dir on remote linux , if it parent dir and dir self  not exists,
        it will mkdir parent dir and dir, else mkdir dir.
        get:  get remote linux  file  to local ,local filename  and remote filename must absolute filepath.
        put:  upload local file to remote linux local filename  and remote filename must absolute filepath.
        rename:
            rename a file or directory on the remote host
            :param str remote_src: the remote file/directory to rename
            :param str remote_dest: the remote file/directory to put it
        open: read remote file content and return readlines list
        cwd : cd  curdir to newdir
        getcwd: get remote linux cursor current dir path and return it
        chmod : change file r,w,x grants.
        chown: change file or dir owner
        opens: read and write  file on remote linux ,if remote file not exists it will create it first  when write .
        exists: if  dir or file exists on remote linux  return True ,else return  False .
        list_dir: query all files  under dir ,the same with shell ls -l -a dir/ .
        ger_recursive:
            recursive copy  remote files or dir under remote dir to localdir
    
    
        put_recursive: recursive copy  localdir's all file or dir under it to remote dir
        """
    
        def __init__(self, ip, port, user, pwd):
            self.ip = ip
            self.port = port
            self.user = user
            self.pwd = pwd
            self.sftp = self.sftp_client()
    
        def sftp_client(self):
            # https://pysftp.readthedocs.io/en/release_0.2.9/cookbook.html#pysftp-cnopts
            # private_key="/home/app/privatekey_file"
            cnopts = pysftp.CnOpts()
            cnopts.hostkeys = None
            sftp = pysftp.Connection(host=self.ip, username=self.user, password=self.pwd, port=self.port, cnopts=cnopts)
            return sftp
    
        def cmd(self, shell_cmd: str):
            """get stdout or err"""
    
            std = self.sftp.execute(shell_cmd)
            if std:
                readlines = ''
                for line in std:
                    readlines = readlines + line.decode("utf-8")
                return readlines
    
        def exists_file(self, filepath):
            try:
                self.sftp.stat(filepath)
            except Exception:
                return False
            else:
                return True
    
        def exists_dir(self, dirpath):
            try:
                self.sftp.stat(dirpath)
            except Exception:
                return False
            else:
                return True
    
        def is_dir(self, dirpath):
    
            return True if self.sftp.isdir(remotepath=dirpath) else False
    
        def is_file(self, filepath):
            return True if self.sftp.isfile(remotepath=filepath) else False
    
        def remove(self, filepath):
            """remove remote file"""
            if self.exists_file(filepath):
                self.sftp.remove(filepath)
            else:
                raise FileNotFoundError("%s file not find on remote ! " % filepath)
    
        def rm(self, dirpath):
            """ rmdir just delete  empty dirs  """
            if self.exists_dir(dirpath):
                files = self.sftp.listdir(dirpath)
                for file in files:
                    filepath = os.path.join(dirpath, file).replace("\",'/')
                    if self.is_dir(filepath):
                        self.rm(filepath)
                    else:
                        self.remove(filepath)
                self.sftp.rmdir(dirpath)
            else:
                raise FileNotFoundError("%s dir not find on remote !" % dirpath)
    
        def mkdir(self, remote_dir):
            """parent dir must exists"""
            if self.exists(remote_dir):
                self.rm(remote_dir)
                self.sftp.mkdir(remotepath=remote_dir)
            else:
                self.sftp.mkdir(remotepath=remote_dir)
    
        def mkdirs(self, remote_dir):
            """mkdir -p /usr/local/mkdir,it can create dir that parent dirs not exists,if exists,it can also create"""
            self.sftp.makedirs(remotedir=remote_dir)
    
        def get(self, remote_path, local_path):
            """sftp get,download """
            self.sftp.get(remotepath=remote_path, localpath=local_path, callback=None)
    
        def put(self, local_path, remote_path):
            """sftp put,upload """
            self.sftp.put(localpath=local_path, remotepath=remote_path)
    
        def rename(self, remote_path, new_name_path):
            """rename file or dir  on remote """
            self.sftp.rename(remote_src=remote_path, remote_dest=new_name_path)
    
        def open(self, remote_filepath, mode):
            """open 'r+' or 'r' file ,return str"""
            readlines = self.sftp.open(remote_file=remote_filepath, mode=mode)
            return list(readlines)
    
        def getcwd(self):
            return self.sftp.getcwd()
    
        def cwd(self, remote_path):
            """change dir to given remote_path"""
            return self.sftp.cwd(remotepath=remote_path)
    
        def chmod(self, remote_path, mode: int):
            """ change file grants for w,r,x"""
            self.sftp.chmod(remotepath=remote_path, mode=mode)
    
        def chown(self, remote_path, uid: int, gid: int):
            """change owner of user and group """
            self.sftp.chown(remote_path, uid, gid)
    
        def chdir(self, remote_path):
            """cwd()== chdir()"""
            self.sftp.chdir(remote_path)
    
        def touch(self, filepath):
            """if exists ,pass it or raise exception """
            if self.exists_file(filepath):
                self.remove(filepath)
                self.sftp_client().execute("touch %s" % filepath)
            else:
                self.sftp_client().execute("touch %s" % filepath)
    
        def close(self):
            self.sftp.close()
    
        def opens(self, filepath, mode, file_data=None):
            """file remote read and write ,return str"""
            tp = paramiko.Transport(self.ip, self.port)
            tp.connect(username=self.user, password=self.pwd)
            pipe = paramiko.sftp_client.SFTPClient.from_transport(tp)
            if mode == "w" or mode == "w+":
                with pipe.open(filepath, mode) as f:
                    f.write(file_data)
            else:
                if mode == "r" or mode == "r+":
                    with pipe.open(filepath, mode)as f:
                        return f.read().decode("utf-8")
        def exists(self,remotepath):
            return True if self.sftp.exists(remotepath)  else False
    
    
        def list_dir(self,dir):
            return self.sftp.listdir(dir)
    
        def get_recursive(self,remote_dir,localpdir,):
            """
            preserve modification time on files if True keep modify file or dir last operate time ,else False
            localpdir : the parent dir path of local receive linux dir
            remote_dir : the target of copy remote_dir ,the result dir name is same with remote
            """
            remote_pdir=os.path.dirname(remote_dir)
            # local_pdir = os.path.dirname(localdir)
            remote_target_dir=os.path.split(remote_dir)[-1]
            self.sftp.chdir(remote_pdir) #cd remote_pdir
            if self.exists(localpdir):
                self.sftp.get_r(remote_target_dir,localpdir,preserve_mtime=False)
            else:
                #local create localdir pdir that not exisit
                os.makedirs(localpdir)
                self.sftp.get_r(remote_target_dir, localpdir, preserve_mtime=False)
    
        def put_recursive(self,localdir,remote_pdir,preserve_mtime=False):
            """
            remote_pdir: the parent dir of receive local targetdir ,if parent exists copy target same
            target dirname diredctly to remote_dir,if parent dir not exists ,first makedirs parent dir of remote_pdir,then copy same name
            target dirname to remote_pdir
            localdir: local target dir absolute dir path
            """
            local_targetdir = os.path.split(localdir)[-1]
            remote_receivedir = os.path.join(remote_pdir, local_targetdir)
            local_pdir=os.path.dirname(localdir)
    
            os.chdir(local_pdir) #cd  local pdir
            if self.sftp.exists(remote_receivedir):
                self.sftp.put_r(local_targetdir,remote_receivedir)
            else:
                #remote create pdir not exists
    
                self.sftp.makedirs(remote_receivedir)
                self.sftp.put_r( local_targetdir,remote_receivedir,preserve_mtime)
    def local_rm(dirpath):
        if os.path.exists(dirpath):
            files = os.listdir(dirpath)
            for file in files:
                filepath = os.path.join(dirpath, file).replace("\",'/')
                if os.path.isdir(filepath):
                    local_rm(filepath)
                else:
                    os.remove(filepath)
            os.rmdir(dirpath)
    
    class TestSftp(unittest.TestCase):
    
    
        @classmethod
        def setUpClass(cls):
            cls.sftp=SftpUtils(ip="192.168.110.151",port=22,user="root",pwd="admin")
        @classmethod
        def  tearDownClass(cls):
            pass
    
    
        def  test_cmd(self):
            shell="ip addr "
            readlines=self.sftp.cmd(shell)
            self.assertIn("192.168.110.151",readlines)
    
        def  test_touch(self):
            path="/usr/local/test.txt"
            self.sftp.touch(path)
            res=self.sftp.exists(path)
            self.assertEqual(res,True)
            r=self.sftp.is_file(path)
            self.assertEqual(r,True)
            self.sftp.remove(path)
            res2 = self.sftp.exists(path)
            self.assertEqual(res2, False)
        def test_isdir(self):
            r=self.sftp.is_dir("/usr/local")
            self.assertEqual(r,True)
            k=self.sftp.is_dir("/fff/fcdh")
            self.assertEqual(k,False)
        def  test_isfile(self):
            r="/usr/tets.txt"
            res=self.sftp.is_file(r)
            self.assertEqual(res,False)
        def test_mkdir(self):
            self.sftp.mkdir("/usr/local/testmkdir")
            r=self.sftp.exists("/usr/local/testmkdir")
            self.assertEqual(r,True)
            # self.sftp.rm("/usr/local/testmkdir")
    
        def test_makedirs(self):
            path="/usr/local/makedirs/mk1"
            self.sftp.mkdirs(path)
            r=self.sftp.exists(path)
            self.assertEqual(r,True)
    
        def test_rm(self):
            path="/usr/local/testrm/rmdir/"
            self.sftp.mkdirs(path)
            files=self.sftp.list_dir("/usr/local/testrm")
            self.assertIn('rmdir',files)
    
            self.sftp.touch(path+"test.txt")
            self.sftp.rm("/usr/local/testrm")
            r=self.sftp.exists(path)
            self.assertEqual(r,False)
        def test_opens(self):
            path="/usr/local/test.txt"
            data={"k":99,"v":{"a":9990},"dd":0,"oo":6556}
            self.sftp.opens(path,'w+',json.dumps(data))
            lines=self.sftp.open(path,'r')
    
    
    
        def test_get_r(self):
            remote="/usr/local/listdir"
            local="/usr/local/ttt"
            # self.sftp.chdir("/usr/local")
            # get current dir
            # print(self.sftp.getcwd())
            self.sftp.get_recursive(remote,local)
            local_rm(local)
    
    
        def test_put_r(self):
            local="/usr/local/upload/listdir"
            remote="/usr/local/rrre"
            self.sftp.put_recursive(local,remote)
            self.sftp.rm(remote)
    
    
    
    if __name__ == '__main__':
        unittest.main(verbosity=2)
    

     测试:

    python   -m  unittest  sftp_tools.TestSftp

    [root@hostuser local]# sh sftptool.sh
    ..........
    ----------------------------------------------------------------------
    Ran 10 tests in 3.017s

    OK

  • 相关阅读:
    scala程序启动时,Could not locate executable nullinwinutils.exe in the Hadoop binaries解决方案
    binlog_format的模式有哪几种?各自的特点是?
    解决IDEA控制台junit不能用Scanner输入问题
    【转】什么是乐观锁,什么是悲观锁
    lyt经典版MySQL基础——流程控制结构
    ambari 2.5.0源码编译安装
    linux(centeros)svn的安装
    机器学习
    算法思想整理
    lucene
  • 原文地址:https://www.cnblogs.com/SunshineKimi/p/11837321.html
Copyright © 2020-2023  润新知