• 并行命令


    需求:创建脚本工具,用于对服务器的批量检查

    1、使用多线程加消息队列形式:

    import paramiko
    import threading
    import sys
    import queue


    #生产者
    class ProSSH(threading.Thread):
    def __init__(self, ips, queue):
    threading.Thread.__init__(self) #继承父类的初始化方法
    self.queue = queue
    self.ips = ips

    def run(self): #重写run方法
    for ip in self.ips:
    self.queue.put(ip)


    #消费者
    class CusSSH(threading.Thread):
    def __init__(self, cmd, queue):
    threading.Thread.__init__(self) #继承父类的初始化方法
    self.queue = queue
    self.cmd = cmd

    def run(self):
    try:
    lock.acquire()
    ip = self.queue.get(1, 5) # 阻塞5秒
    self.ssh_conn(ip)
    lock.release()
    except:
    return

    def ssh_conn(self, ip):
    ssh = paramiko.SSHClient() # 创建链接对象
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥
    pkey_file = '/root/.ssh/id_rsa' # 指定私钥位置
    key = paramiko.RSAKey.from_private_key_file(pkey_file, password='123456') # 创建秘钥链接对象,密码为创建秘钥时设置的,没有设置就留空
    try:
    ssh.connect(hostname=ip, username='root', pkey=key, timeout=1)
    except:
    print("Timeout or not parmission")
    return 1
    stdin, stdout, stderr = ssh.exec_command(self.cmd) # 输出会分别保存到三个文件里
    stdout = stdout.read()[:-1] # [:-1]指的是去掉最后一个字符,因为这个最后输出会有个换行符
    stderr = stderr.read()[:-1]
    if stdout:
    print("{0}: {1}".format(ip, stdout))
    ssh.close()
    else:
    print("{0}: {1}".format(ip, stderr))
    ssh.close()

    if __name__ == '__main__':
    paramiko.util.log_to_file('/root/python/paramikos/paramiko.log') # 输出日志
    queue = queue.Queue(10) # 创建消息队列,最大长度10
    lock = threading.Lock()
    ips = ['192.168.137.' + str(i) for i in range(10, 101)]
    try:
    cmd = sys.argv[1]
    except Exception as e:
    print("{0} follow a command".format(__file__))
    sys.exit(1)
    t1 = ProSSH(ips, queue)
    t1.start()
    for i in range(len(ips)):
    t2 = CusSSH(cmd, queue)
    t2.start()

    2、使用进程池形式:

    import paramiko
    import multiprocessing
    import sys


    def ssh_conn(ip, cmd):
    ssh = paramiko.SSHClient() # 创建链接对象
    ssh.set_missing_host_key_policy(
    paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存>下本机的秘钥
    pkey_file = '/root/.ssh/id_rsa' # 指定私钥位置
    key = paramiko.RSAKey.from_private_key_file(pkey_file, password='123456') # 创建秘钥链接对象,密码为创建秘钥时设置的,没有设置就留空
    try:
    ssh.connect(hostname=ip, username='root', pkey=key, timeout=1)
    except:
    print("Timeout or not parmission")
    return 1
    stdin, stdout, stderr = ssh.exec_command(cmd) # 输出会分别保存到三个文件里
    stdout = stdout.read()[:-1] # [:-1]指的是去掉最后一个字符,因为这个最后输出会有个换行符
    stderr = stderr.read()[:-1]
    if stdout:
    print("{0}: {1}".format(ip, stdout))
    ssh.close()
    else:
    print("{0}: {1}".format(ip, stderr))
    ssh.close()

    if __name__ == '__main__':
    paramiko.util.log_to_file('/root/python/paramikos/paramiko.log') # 输出日志
    ips = ['192.168.137.' + str(i) for i in range(10, 101)]
    try:
    cmd = sys.argv[1]
    except Exception as e:
    print("{0} follow a command".format(__file__))
    sys.exit(1)
    pool = multiprocessing.Pool(processes=10) #开启10个进程池
    for ip in ips:
    pool.apply_async(func=ssh_conn, args=(ip, cmd)) #异步进程
    pool.close()
    pool.join() #阻塞主进程

    3、使用进程池加参数形式:

    import paramiko
    import multiprocessing
    import sys
    from optparse import OptionParser


    def opt():
    parser = OptionParser("Usage: %prog -a command")
    parser.add_option('-a',
    dest = 'addr',
    action = 'store',
    help = 'ip or iprange, EX: 192.168.1.1,192.168.1.3 or 192.168.1.1-192.168.1.3')
    options, args = parser.parse_args()
    return options, args

    def parseOpt(option):
    if ',' in option:
    ips = option.split(',')
    return ips
    elif '-' in option:
    ip_start, ip_end = option.split('-')
    ip_net = '.'.join(ip_start.split('.')[:-1])
    start = int(ip_start.split('.')[-1])
    end = int(ip_end.split('.')[-1]) + 1
    ips = [ip_net + '.' + str(i) for i in range(start, end)]
    return ips
    elif ',' not in option or '-' not in option:
    ips = [option]
    return ips
    else:
    print("{0} -h".format(__file__))

    def ssh_conn(ip, cmd):
    ssh = paramiko.SSHClient() # 创建链接对象
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存>下本机的秘钥
    pkey_file = '/root/.ssh/id_rsa' # 指定私钥位置
    key = paramiko.RSAKey.from_private_key_file(pkey_file, password='123456') # 创建秘钥链接对象,密码为创建秘钥时设置的,没有设置就留空
    try:
    ssh.connect(hostname=ip, username='root', pkey=key, timeout=1)
    except:
    print("Timeout or not parmission")
    return 1
    stdin, stdout, stderr = ssh.exec_command(cmd) # 输出会分别保存到三个文件里
    stdout = stdout.read()[:-1] # [:-1]在这里的作用是去掉最后一个字符,因为这个最后输出会有个换行符
    stderr = stderr.read()[:-1]
    if stdout:
    print("{0}: {1}".format(ip, stdout))
    ssh.close()
    else:
    print("{0}: {1}".format(ip, stderr))
    ssh.close()


    if __name__ == '__main__':
    paramiko.util.log_to_file('/root/python/paramikos/paramiko.log') # 输出日志
    options, args = opt()
    try:
    cmd = args[0]
    except:
    print("{0} follow a command".format(__file__))
    sys.exit(1)
    if options.addr:
    ips = parseOpt(options.addr)
    else:
    print("{0} -h".format(__file__))
    sys.exit(1)
    pool = multiprocessing.Pool(processes=10) #开启10个进程池
    for ip in ips:
    pool.apply_async(func=ssh_conn, args=(ip, cmd)) #异步进程
    pool.close()
    pool.join() #阻塞主进程
  • 相关阅读:
    html标签
    正则表达式判断号码靓号类型
    power函数:求底的n次幂
    php5.3的新特性
    xml方式操作txt文件
    什么是闭包?
    php设计模式单例模式
    面试总结
    统计ip代码
    XSL语言学习
  • 原文地址:https://www.cnblogs.com/Jweiqing/p/9118628.html
Copyright © 2020-2023  润新知