Paramiko模块实现Linux下多并发scp/ssh以及xshell客户端

2 篇文章 0 订阅
1 篇文章 0 订阅
***环境是在Linux/Unix主机之间****
###需求
1、一台主机无密码登录其他主机进行操作(如同:SCRT)
2、不用登录其他主机就能实现主机命令执行
3、远程下载、上传文件
4、远程多并发上传、下载文件夹
5、操作方式类似于Linux scp/ssh命令操作

###主要使用工具及技术
1、paramiko模块的shell、sftp、ssh相关功能;
2、多进程并发;
3、进程队列与事件的结合使用;
4、使用到多进程子嵌套的方式完成功能;
5、内置模块logging的使用;


###工具使用方式及相关说明如下:
python sh_stp_main.py -xsh account@192.168.1.1 (执行一个远程xshell终端)
python sh_stp_main.py -sh account@192.168.1.1 'df -h' (执行远程shell命令并返回结果)
python sh_stp_main.py -put 本地文件 account@192.168.1.1:远程文件/目录(上传文件到远程主机)
python sh_stp_main.py -get account@192.168.1.1:远程文件 本地文件/目录(从远程主机下载文件)
python sh_stp_main.py -putdir 本地文件/目录 account@192.168.1.1:远程文件/目录(上传文件/目录到远程主机)
python sh_stp_main.py -getdir account@192.168.1.1:远程文件/目录 本地文件/目录(下载文件/目录到本地主机)

在sh_stp_main.py的字典中定义主机相关信息;

主要控制模块如下,详细见GitHub源码项目

 

# !/usr/bin/env python
__author__ = 'yuanwm <ywmpsn@163.com>'

# -*- encoding: utf-8 -*-

from paramiko_sh import SSHConnection
from multistp import MultiSftp
import sys


'''
在这里定义IP与用户名以及密码,暂时使用字典定义(防止无第三方的模块解析配置文件)
'''
HostMsg = {
    "account@192.168.1.7": {
        "HostPassWord": "111111",
        "HostPort": "22"
    },
    "account@10.113.78.111": {
        "HostPassWord": "111111",
        "HostPort": "22"
    }
}


def get_host_msg(host_name_ip):
    """
    根据用户名与ip获取主机的密码与端口信息
    :param host_name_ip: 如:account@192.168.1.7
    :return:
    """
    # 获取密码
    if host_name_ip not in HostMsg:
        raise Exception('无主机[%s]信息!' % host_name_ip)
    if "HostPassWord" not in HostMsg[HostNameIp]:
        raise Exception('无主机[%s]密码配置信息!' % host_name_ip)
    host_password = HostMsg[host_name_ip]["HostPassWord"]
    if "HostPort" not in HostMsg[host_name_ip]:
        raise Exception('无主机[%s]端口配置信息!' % host_name_ip)
    host_port = HostMsg[host_name_ip]["HostPort"]

    return host_password, host_port


if __name__ == "__main__":
    '''
    选择方式执行对应的操作
    '''
    # 传入参数判断,至少有两个参数:argv【1】 操作,argv[2]
    if len(sys.argv) < 3:
        sys.stderr.write('''执行方式错误!,例如:
python %s -xsh account@192.168.1.1 (执行一个远程xshell终端)
python %s -sh account@192.168.1.1 'df -h' (执行远程shell命令并返回结果)
python %s -put 本地文件 account@192.168.1.1:远程文件/目录(上传文件到远程主机)
python %s -get account@192.168.1.1:远程文件 本地文件/目录(从远程主机下载文件)
python %s -putdir 本地文件/目录 account@192.168.1.1:远程文件/目录(上传文件/目录到远程主机)
python %s -getdir account@192.168.1.1:远程文件/目录 本地文件/目录(下载文件/目录到本地主机)
''' % (sys.argv[0], sys.argv[0], sys.argv[0], sys.argv[0], sys.argv[0], sys.argv[0]))
        sys.stderr.flush()
        exit(1)

    # ip参数解析
    OperaType = sys.argv[1]
    try:
        if OperaType == '-xsh':  # xshell窗口
            HostNameIp = sys.argv[2]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            ssh = SSHConnection(HostIp, HostPort, HostName, HostPassword)
            ssh.connect()
            ssh.x_shell()
            ssh.disconnect()
        elif OperaType == '-sh':    # 执行远程shell命令
            if len(sys.argv) < 4:
                sys.stderr.write('''参数错误!,例如:
                python %s -sh account@192.168.1.1 'df -h' (执行远程shell命令并返回结果)
                ''' % sys.argv[0])
                sys.stderr.flush()
                exit(1)
            HostNameIp = sys.argv[2]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            command = sys.argv[3]
            ssh = SSHConnection(HostIp, HostPort, HostName, HostPassword)
            ssh.connect()
            ssh.shell_cmd(command)
            ssh.disconnect()
        elif OperaType == '-put':   # 上传文件
            if len(sys.argv) < 4:
                sys.stderr.write('''参数错误!,例如:
                python %s -put 本地文件 account@192.168.1.1:远程文件/目录(上传文件到远程主机)
                ''' % sys.argv[0])
                sys.stderr.flush()
                exit(1)
            RemoteMsg = sys.argv[3]
            HostNameIp = RemoteMsg.split(':')[0]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            ssh = SSHConnection(HostIp, HostPort, HostName, HostPassword)
            ssh.connect()
            remote_path = RemoteMsg.split(':')[1]
            local_path = sys.argv[2]
            ssh.sftp_put(local_path, remote_path)
            ssh.disconnect()
        elif OperaType == '-get':   # 下载文件
            if len(sys.argv) < 5:
                sys.stderr.write('''参数错误!,例如:
                python %s -get account@192.168.1.1:远程文件 本地文件/目录(从远程主机下载文件)
                ''' % sys.argv[0])
                sys.stderr.flush()
                exit(1)
            RemoteMsg = sys.argv[2]
            HostNameIp = RemoteMsg.split(':')[0]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            ssh = SSHConnection(HostIp, HostPort, HostName, HostPassword)
            ssh.connect()
            remote_path = RemoteMsg.split(':')[1]
            local_path = sys.argv[3]
            ssh.sftp_get(remote_path, local_path)
            ssh.disconnect()
        elif OperaType == '-getdir':    # 下载目录
            if len(sys.argv) < 4:
                sys.stderr.write('''参数错误!,例如:
                python %s -getdir account@192.168.1.1:远程文件/目录 本地文件/目录(下载文件/目录到本地主机)
                ''' % sys.argv[0])
                sys.stderr.flush()
                exit(1)
            RemoteMsg = sys.argv[2]
            HostNameIp = RemoteMsg.split(':')[0]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            remote_path = RemoteMsg.split(':')[1]
            local_path = sys.argv[3]
            # 最大进程数定义
            max_process_num = 0
            if len(sys.argv) > 4:
                max_process_num = int(sys.argv[4])
            else:
                max_process_num = 5
            multi_sftp = MultiSftp(HostIp, HostPort, HostName, HostPassword)
            multi_sftp.sftp_get_dir(local_path, remote_path, max_process_num)
        elif OperaType == '-putdir':    # 上传目录
            if len(sys.argv) < 4:
                sys.stderr.write('''参数错误!,例如:
                python %s -putdir 本地文件/目录 account@192.168.1.1:远程文件/目录(上传文件/目录到远程主机)
                ''' % sys.argv[0])
                sys.stderr.flush()
                exit(1)
            RemoteMsg = sys.argv[3]
            HostNameIp = RemoteMsg.split(':')[0]
            HostName = HostNameIp.split('@')[0]
            HostIp = HostNameIp.split('@')[1]
            (HostPassword, HostPort) = get_host_msg(HostNameIp)
            remote_path = RemoteMsg.split(':')[1]
            local_path = sys.argv[2]
            # 最大进程数定义
            max_process_num = 0
            if len(sys.argv) > 4:
                max_process_num = int(sys.argv[4])
            else:
                max_process_num = 5
            multi_sftp = MultiSftp(HostIp, HostPort, HostName, HostPassword)
            multi_sftp.sftp_put_dir(local_path, remote_path, max_process_num)
        else:
            sys.stderr.write("不支持操作类型[%s]\n" % OperaType)
            sys.stderr.flush()
            exit(1)
    except Exception as ErrMsg:
        sys.stderr.write('操作[%s]执行错误![%s]\n' % (ErrMsg, OperaType))
        sys.stderr.flush()
        exit(1)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值