操作远程linux文件

# coding=utf-8
"""
操作远程linux文件
"""
import paramiko
import os
import time
from pathlib import Path
from optparse import  OptionParser
from concurrent.futures import ThreadPoolExecutor

def sftp_download_file(sftp, remote_file, local_file=None, local_dir=None):
    """
    下载单个文件
    :param sftp: sftp 连接
    :param remote_file: 远程文件路径
    :param local_file: 本地文件路径
    :param local_dir: 本地文件目录路径
    :return:
    """
    if local_dir:
        local_file = local_dir + '/' + os.path.basename(remote_file)
    local_file = Path(local_file).as_posix()
    remote_file = Path(remote_file).as_posix()
    try:
        sftp.file(remote_file)
    except FileNotFoundError:
        print("[ERROR]: 下载文件不存在...:信息如下", "远程目录路径:", remote_file)
        return False
    try:
        sftp.get(remote_file, local_file)  # 下载目录中文件
    except IOError as e :
        print("[ERROR]: 下载失败...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file, "ERROR:", e)
        return False
    print("[INFO]: 下载文件完成:信息如下", "远程文件路径:", remote_file, "本地文件路径:", local_file)
    return True


def sftp_download_dir(sftp, local_dir, remote_dir):
    """
    下载整个目录下的文件
    :param sftp: sftp 连接
    :param local_dir: 本地文件路径
    :param remote_dir: 远程文件路径
    :return:
    """
    local_dir = Path(local_dir).as_posix()
    remote_dir = Path(remote_dir).as_posix()
    print("[INFO]: 开始下载文件目录...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
    if not os.path.exists(local_dir):
        os.makedirs(local_dir)
    try:
        sftp.file(remote_dir)
    except FileNotFoundError :
        print("[ERROR]: 下载文件目录不存在...:信息如下", "远程目录路径:", remote_dir)
        return False
    if not sftp.listdir(remote_dir):
        print("[INFO]: 下载文件目录为空...:信息如下", "远程目录路径:", remote_dir,)
        return True
    for file in sftp.listdir(remote_dir):
        local = os.path.join(local_dir, file)
        remote = remote_dir + '/' + file
        remote = Path(remote).as_posix()
        if 'd' == str(sftp.stat(remote))[0] : #d:目录文件,l:链接文件,b:设备文件,c:字符设备文件,p:管道文件
            if not os.path.exists(local):
                os.makedirs(local)
            sftp_download_dir(sftp=sftp, local_dir=local, remote_dir=remote)
        else:  # 文件
            sftp_download_file(sftp=sftp, local_file=local, remote_file=remote)
    print("[INFO]: 下载文件目录完成...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
    return True


def sftp_upload_file(sftp, local_file, remote_file=None, remote_dir=None):
    """
    上传文件
    :param sftp:
    :param local_file: 本地文件路径
    :param remote_file: 远程文件路径
    :param remote_dir: 远程文件目录路径
    :return:
    """
    if remote_dir:
        remote_file =  remote_dir + '/' + os.path.basename(local_file)

    local_file = Path(local_file).as_posix()
    remote_file = Path(remote_file).as_posix()
    # print("[INFO]: 开始上传文件...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file)
    if not os.path.exists(local_file):
        print("[ERROR]: 上传本地文件不存在...:信息如下" "本地目录路径:", local_file)
        return False
    try:
        sftp.put(local_file, remote_file)
    except IOError  as e:
        print("[ERROR]: 上传失败...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file, "ERROR:", e)
        return False
    print("[INFO]: 上传文件完成...:信息如下", "远程目录路径:", remote_file, "本地目录路径:", local_file)
    return True

def sftp_mkdir(sftp,remote_dir):
    """
    创建文件目录
    :param sftp:
    :param remote_dir:远程文件路径
    :return:
    """
    remote_dir = Path(remote_dir).as_posix()
    try:
        sftp.file(remote_dir)
        print("[WARING]: 创建文件目录已存在...:信息如下", "远程目录路径:", remote_dir)
        return True
    except FileNotFoundError:
        try:
            sftp.mkdir(remote_dir)
        except IOError as e :
            print("[ERROR]: 创建文件目录失败...:信息如下", "远程目录路径:", remote_dir, "ERROR:", e)
            return False
        print("[INFO]: 创建文件目录...:信息如下", "远程目录路径:", remote_dir)
        return True


def sftp_upload_dir(sftp, local_dir, remote_dir):
    """
    上传目录
    :param sftp:
    :param local_dir: 本地文件路径
    :param remote_dir: 远程文件路径
    :return:
    """
    local_dir = Path(local_dir).as_posix()
    remote_dir = Path(remote_dir).as_posix()
    print("[INFO]: 开始上传文件目录...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)
    if not Path(local_dir).is_dir():
        print("[ERROR]: 上传文件目录不存在...:信息如下", "本地目录路径:", local_dir)
    sftp_mkdir(sftp=sftp, remote_dir=remote_dir)

    for root, dirs, files in os.walk(local_dir):
        for dir in dirs:
            local_path = os.path.join(root, dir)
            dir_name = local_path.replace(local_dir, '')
            remote_path = remote_dir + os.sep + dir_name
            sftp_mkdir(sftp=sftp, remote_dir=remote_path)
        for file in files:
            local_file = os.path.join(root, file)
            file_name = local_file.replace(local_dir, '')
            remote_file = remote_dir + os.sep + file_name
            sftp_upload_file(sftp=sftp, local_file =local_file, remote_file=remote_file)
    print("[INFO]: 上传文件目录完成...:信息如下", "远程目录路径:", remote_dir, "本地目录路径:", local_dir)

def ssh_conn(host, username='root', password='123456', port=22):
    """
    获取 ssh 连接
    :param host:
    :param username:
    :param password:
    :param port:
    :return:
    """
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname=host, username=username, password=password, port=port, allow_agent=False, look_for_keys=False)
    return ssh


def format_time(times=time.time(), format='%Y%m%d%H%M%S'):
    '''
    格式化日期
    :param times:
    :return:
    '''
    return time.strftime(format, time.localtime(times))


def test_case():
    ssh = ssh_conn(host='106.13.4.188', username='root', password='wang@3715', port=22)
    sftp = ssh.open_sftp()

    # 创建线程池  指定最大容纳数量
    EXECUSTOR = ThreadPoolExecutor(max_workers=options.maxworkers)
    # 下载文件目录
    # local_dir = './data/' + format_time()  # 本地文件
    # remote_dir = '/home/wwl'  # 远程文件或目录
    # sftp_download_dir(sftp=sftp, local_dir=local_dir, remote_dir=remote_dir)

    # 下载文件
    # local_dir = './data/' + format_time()  # 本地文件
    # remote_file = '/home/log.log'  # 远程文件或目录
    # os.makedirs(local_dir)
    # sftp_download_file(sftp=sftp, local_dir=local_dir, remote_file=remote_file)

    # 上传 文件目录
    # local_dir = r"D:\fuck\Java"  # 本地文件
    # remote_dir = '/home/wwl/TEMP'  # 远程文件或目录
    # sftp_upload_dir(sftp=sftp, local_dir=local_dir, remote_dir=remote_dir)

    # 上传 文件文件
    # local_file = r"D:\fuck\AI\Tensorflow.emmx"  # 本地文件
    # remote_dir = '/home/TEMP'  # 远程文件或目录
    # sftp_upload_file(sftp=sftp, local_file=local_file, remote_dir=remote_dir)
    sftp.close()
    ssh.close()


def main(options):
    ssh = ssh_conn(host=options.ip, username=options.username, password=options.password, port=options.port)
    sftp = ssh.open_sftp()
    if options.isupload :#上传
        if options.localdir :
            if options.remotedir:
                sftp_upload_dir(sftp=sftp, local_dir=options.localdir, remote_dir=options.remotedir)
            else:
                print("[ERROR]:","The upload directory must correspond to the remote directory")
        elif options.localfile:
            sftp_upload_file(sftp=sftp, local_file=options.localfile, remote_file=options.remotefile, remote_dir=options.remotedir)
        else:
            print("[ERROR]:", "The local file path is not configured")

    else: # 下载
        if options.remotedir :
            if options.localdir :
                sftp_download_dir(sftp=sftp, local_dir=options.localdir, remote_dir=options.remotedir)
            else:
                print("[ERROR]:", "The download remote server directory must exist in the corresponding local directory")
        elif options.remotefile:
                sftp_download_file(sftp=sftp, remote_file=options.remotefile, local_file=options.localfile, local_dir=options.localdir)
        else:
            print("[ERROR]:", "The remote servers file path is not configured")
    sftp.close()
    ssh.close()

if __name__ == '__main__':
    usage = '[*] Usage : such as: ' + os.path.basename(__file__) +  \
            ' -i 127.0.0.1 -u root -p 123456 -T true -d ./data -r /home/temp'

    parser = OptionParser(usage)

    parser.add_option('-i', '--ip', dest='ip', type='string', help='specify remote servers ip')
    parser.add_option('-u', '--user', dest='username', type='string', help='specify remote servers username')
    parser.add_option('-p', '--password', dest='password', type='string', help='specify remote servers clientpassword')
    parser.add_option('-P', '--port', dest='port', type='int', help='specify remote servers port,default 22', default=22)
    parser.add_option('-T', '--isupload', dest='isupload', type='string', help='Whether to upload files, default False', default=False)
    parser.add_option('-d', '--localdir', dest='localdir', type='string', help='local file directory path: either-or localfile')
    parser.add_option('-f', '--localfile', dest='localfile', type='string', help='local file path')
    parser.add_option('-r', '--remotedir', dest='remotedir', type='string', help='remote servers file directory path : either-or remotefile')
    parser.add_option('-t', '--remotefile', dest='remotefile', type='string', help='remote servers file path')
    (options, args) = parser.parse_args()

    #远程服务SSH登录 参数
    if (options.ip == None) | (options.username == None) | (options.password == None):
        print("[ERROR]:", parser.usage)
        exit(1)
    #传输文件路径 参数
    if (options.localdir == None and options.localfile == None) | (options.remotedir == None and options.remotefile == None):
        print("[ERROR]:", parser.usage)
        exit(1)

    #主函数
    main(options)

    exit(0)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lanlingxueyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值