Implementation of non interactive sftp upload and download with Python

Keywords: sftp Python Windows ssh

Copyright notice: This is the original article of the blogger. It can't be reproduced without the permission of the blogger. https://blog.csdn.net/u010950854/article/details/62233538

Implementation of non interactive sftp upload and download with Python

Install Paramiko

Python's Library Paramiko implements the ssh and sftp protocols, which are very powerful, but they are usually not included. Let's install them first. Enter pip install paramiko on a machine that can be networked and wait for the installation to complete.

Realization

First, introduce various libraries

os to traverse the folder, platform to determine the operating system, sys to take the incoming parameters, paramiko to achieve various operations of sftp.

# coding=utf-8
import os  
import paramiko  
import platform
import sys

Upload files and directories

Code

def upload(ip, port, username, password, local, remote):  
    #Upload directory or file
    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):#Determine whether the local parameter is a directory or a file
            print 'upload dir'
            for root, dirs, files in os.walk(local):  #Traverse local directory
                for file_name in files:  
                    local_file_path = os.path.join(root, file_name)
                    # Slicing: removing drive letter from windows path  
                    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)
                    # Slicing: removing drive letter from windows path
                    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)
                # There is no target file name in remote. Use local filename
                if remote_filename == ''  or remote_filename == '.': 
                    remote_filename = local_filename
                # There is no target directory in remote, use the default directory
                if remote_dir == '': 
                    remote_dir = '.'
                try:
                    sftp.chdir(remote_dir) # Switch to destination directory
                    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()
  • Download files and directories
def download(host,port,username,password,remote,local):
    # Download file or directory
    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
            # If no file name is entered, use the file name of 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()
  •  

Example

  1. Download testdir1 to testdir2
download('ip', 'port', 'username', 'password', 'testdir1', 'testdir2')
  • 1
  1. Download testfile1 to the current directory
download('ip', 'port', 'username', 'password', 'testdir6/testfile1', '')
  • 1
  1. Upload files to default directory
upload('ip', 'port', 'username', 'password', 'file1', '.')
  • 1
  1. Upload directory to specified directory
upload('ip', 'port', 'username', 'password', 'testdir1', 'testdir2')
  • 1

Pack as command

Save to sftp.py at, and then upload and download without interaction through python sftp.py get username/password@ip:port remote local, Python sftp.py put username / password @ IP: port loadL remote in the shell script.

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'

Posted by j0hn_ on Sun, 05 Jan 2020 10:39:26 -0800