Pythonを使用してインタラクティブなsftpのアップロード、ダウンロードを実現

14101 ワード

Pythonでインタラクティブなsftpのアップロード、ダウンロードを実現
Paramikoのインストール
PythonのライブラリParamikoはsshとsftpプロトコル機能を実現していますが、一般的には持っていませんので、まずインストールしてみましょう.ネットワーク接続可能な機器にpip install paramikoを入力し、設置完了を待つ.
インプリメンテーション
まず各種ライブラリを導入する
osはフォルダを巡り、platformはオペレーティングシステムを判断し、sysは入力したパラメータを取り、paramikoはsftpの様々な操作を実現する.
# coding=utf-8
import os  
import paramiko  
import platform
import sys

ファイル、ディレクトリのアップロード
コード#コード#
def upload(ip, port, username, password, local, remote):  
    #     or   
    paramiko.util.log_to_file("paramiko.log")  
    trans = paramiko.Transport((ip, int(port)))  
    trans.connect(username=username, password=password)  
    sftp = paramiko.SFTPClient.from_transport(trans)   
    try:  
        sftp.mkdir(remote)  
    except Exception, e:  
        print e,'mkdir',remote , 'fail, dir is exists'
    try:
        if os.path.isdir(local):#             
            print 'upload dir'
            for root, dirs, files in os.walk(local):  #      
                for file_name in files:  
                    local_file_path = os.path.join(root, file_name)
                    #   :windows        
                    if(platform.system() == 'Windows'):
                        remote_file_path = os.path.join(  
                        remote_dir, local_file_path[3:])      
                    else:
                        remote_file_path = os.path.join(  
                        remote_dir, local_file_path)    
                    remote_file_path = remote_file_path.replace("\\", "/")  

                    try:  
                        sftp.put(local_file_path, remote_file_path)  
                    except Exception, e:  
                        print e,'put',local_file_path,'to'
                            ,remote_file_path,'fail'
                        sftp.mkdir(os.path.dirname(remote_file_path))  
                        sftp.put(local_file_path, remote_file_path)  
                for dir_name in dirs:  
                    local_dir = os.path.join(root, dir_name)
                    #   :windows      
                    if(platform.system() == 'Windows'):
                        remote_path = os.path.join(remote, local_dir[3:])  
                    else:
                        remote_path = os.path.join(remote, local_dir) 
                    remote_path = remote_path.replace("\\", "/")  

                    try:  
                        sftp.mkdir(os.path.dirname(remote_path))  
                        sftp.mkdir(remote_path)  
                    except Exception, e:  
                        print e,'mkdir',remote_path,'on remote fail'  
        else:
            print 'upload file'
            try:
                remote_dir,remote_filename  =  os.path.split(remote)
                local_dir,local_filename = os.path.split(local)
                # remote        ,  local_filename
                if remote_filename == ''  or remote_filename == '.': 
                    remote_filename = local_filename
                # remote        ,      
                if remote_dir == '': 
                    remote_dir = '.'
                try:
                    sftp.chdir(remote_dir) #        
                    sftp.put(local,remote_filename) 
                except Exception, e:  
                    print e,remote_dir,'is not exists'      
            except Exception, e:  
                print e,'put',local,'to',remote,'fail'  
        trans.close()
    except Exception, e:  
        print e   
        trans.close()

ファイル、ディレクトリのダウンロード
def download(host,port,username,password,remote,local):
    #      or   
    paramiko.util.log_to_file("paramiko.log")  
    sf = paramiko.Transport((host,port))
    sf.connect(username = username,password = password)
    sftp = paramiko.SFTPClient.from_transport(sf)
    print local,remote   
    def getall(remote,local):
        print 'prarms',remote,local
        if stat.S_ISREG(sftp.stat(remote).st_mode):
            print remote,'is file,get to',os.path.join(local,remote)
            sftp.get(remote,os.path.join(local,remote))
            return
        else:
            print remote,'is dir,mkdir at',os.path.join(local,remote)
            os.mkdir(os.path.join(local,remote))
            for f in sftp.listdir_attr(remote):
                getall(os.path.join(remote,f.filename),local) 

    try:
        #1.local is file or dir, remote is file
        if stat.S_ISREG(sftp.stat(remote).st_mode): # remote is file
            local_dir,local_filename = os.path.split(local) 
            print local_dir,local_filename 
            remote_dir,remote_filename = os.path.split(remote)
            print remote_dir,remote_filename
            #            remote     
            if local_filename == '' and local_filename != '.': 
                print 'without a filename'          
                sftp.get(remote,os.path.join(local,remote_filename))
            else:
                print 'have a filename'
                sftp.get(remote,local)
        else: #remote is dir
            getall(remote,local)        
        trans.close()
    except Exception, e:
        print e
        trans.close()

  • ダウンロードディレクトリtestdir 1からtestdir 2下
  • download('ip', 'port', 'username', 'password', 'testdir1', 'testdir2')
  • ファイルtestfile 1を現在のディレクトリ
  • にダウンロード
    download('ip', 'port', 'username', 'password', 'testdir6/testfile1', '')
  • ファイルをデフォルトディレクトリ
  • にアップロード
    upload('ip', 'port', 'username', 'password', 'file1', '.')
  • は、指定ディレクトリ
  • にディレクトリをアップロードする.
    upload('ip', 'port', 'username', 'password', 'testdir1', 'testdir2')

    パッケージコマンドsftp.pyに保存し、shellスクリプトでpython sftp.py get username/password@ip:port remote localpython sftp.py put username/password@ip:port loacl remoteを介してインタラクティブにアップロード、ダウンロードすることができます.
    if __name__ == '__main__':
        #python sftp.py username/password@ip:port get remote local
        #python sftp.py username/password@ip:port upload remote local
    
        if len(sys.argv) < 5 :
            print 'sftp.py takes 4 argument (',(len(sys.argv)-1), 'given)'
            print 'get file or dir: get username/password@ip:port remote local'
            print 'put file or dir: put username/password@ip:port loacl remote'
            return
        op = sys.argv[1]
        un,pw = sys.argv[2].split('/')
        pw,ip = pw.split('@')
        if ip.rfind(':') != -1:
            ip,port = ip.split(':')
        else:
            port = 22
        print op,ip,port,un,pw
    
        if sys.argv[1] == 'get' 
            download(ip,port,un,pwd,sys.argv[3],sys.argv[4])
        elif sys.argv[1] != 'put':
            upload(ip,port,un,pwd,sys.argv[4],sys.argv[3])
        else:
            print 'invlid type:' ,sys.argv[1]
            print 'get file or dir: get username/password@ip:port remote local'
            print 'put file or dir: put username/password@ip:port loacl remote'