Python远程获取Linux信息

本文知识点:paramiko模块

介绍见另外一篇文章: Python之paramiko

1.sshlinux.py

#sshlinux.py
import paramiko
 
class SSHParamiko():
 
    err = "argument passwd or rsafile can not be None"
 
    def __init__(self, host, port, user, passwd=None, rsafile=None):
        self.h = host
        self.p = port
        self.u = user
        self.w = passwd
        self.rsa = rsafile
 
    def _connect(self):
        if self.w:
            return self.pwd_connect()
        elif self.rsa:
            return self.rsa_connect()
        else:
            raise ConnectionError(self.err)
 
    def _transfer(self):
        if self.w:
            return self.pwd_transfer()
        elif self.rsa:
            return self.rsa_transfer()
        else:
            raise ConnectionError(self.err)
 
    def pwd_connect(self):
        conn = paramiko.SSHClient()
        conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        conn.connect(self.h, self.p, self.u, self.w)
        return conn
 
    def rsa_connect(self):
        pkey = paramiko.RSAKey.from_private_key_file(self.rsa)
        conn = paramiko.SSHClient()
        conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        conn.connect(hostname=self.h, port=self.p, username=self.u, pkey=pkey)
        return conn
 
    def pwd_transfer(self):
        transport = paramiko.Transport(self.h, self.p)
        transport.connect(username=self.u, password=self.w)
        sftp = paramiko.SFTPClient.from_transport(transport)
        return sftp, transport
 
    def rsa_transfer(self):
        pkey = paramiko.RSAKey.from_private_key_file(self.rsa)
        transport = paramiko.Transport(self.h, self.p)
        transport.connect(username=self.u, pkey=pkey)
        sftp = paramiko.SFTPClient.from_transport(transport)
        return sftp, transport
 
    def run_cmd(self, cmd):
        conn = self._connect()
        stdin, stdout, stderr = conn.exec_command(cmd)
        code = stdout.channel.recv_exit_status()
        stdout, stderr = stdout.read(), stderr.read()
        conn.close()
        if not stderr:
            return code, stdout.decode()
        else:
            return code, stderr.decode()

    def get_file(self, remote, local):
        sftp, conn = self._transfer()
        sftp.get(remote, local)
        conn.close()

    def put_file(self, local, remote):
        sftp, conn = self._transfer()
        sftp.put(local, remote)
        conn.close()
        
if __name__ == '__main__':
    with open ("hosts.txt") as f:
        for line in f:
            h = line.split(',')[0];
            p = line.split(',')[1];
            u = line.split(',')[2];
            w = line.split(',')[3].strip("\n");

            print(h)
            obj = SSHParamiko(h, p, u, w)
            r = obj.run_cmd("free -m")
            print(r[1])

运行结果:

============================= RESTART: E:\py\sshlinux.py ============================
192.168.244.134
              total        used        free      shared  buff/cache   available
Mem:           1821        1514          70          52         236          75
Swap:          8191           3        8188

192.168.244.130
              total        used        free      shared  buff/cache   available
Mem:            972         110         703           7         157         690
Swap:          2047           0        2047

>>> 

2.并发执行,并根据运行结果显示不同的颜色

from concurrent.futures import ThreadPoolExecutor
from colorama import init

init(autoreset=True)

class AllRun(object):
    
    def __init__(self, ssh_objs, cmds, max_worker=50):
        self.objs = [o for o in ssh_objs]
        self.cmds = [c for c in cmds]
        self.max_worker = max_worker  # 最大并发线程数

        self.success_hosts = []       # 存放成功机器数目
        self.failed_hosts = []        # 存放失败的机器IP
        self.mode = None
        self.func = None

    def serial_exec(self, obj):
        """单台机器上串行执行命令,并返回结果至字典"""
        result = list()
        for c in self.cmds:
            r = obj.run_cmd(c)
            result.append([c, r])
        return obj, result
 
    def concurrent_run(self):
        """并发执行"""
        future = ThreadPoolExecutor(self.max_worker)
        for obj in self.objs:
            try:
                future.submit(self.serial_exec, obj).add_done_callback(self.callback)
            except Exception as err:
                err = self.color_str(err, "red")
                print(err)
        future.shutdown(wait=True)

    def callback(self, future_obj):
        """回调函数,处理返回结果"""
        ssh_obj, rlist = future_obj.result()
        print(self.color_str("{} execute detail:".format(ssh_obj.h), "green"))
        is_success = True
        for item in rlist:
            cmd, [code, res] = item
            info = f"{cmd} | code => {code}\nResult:\n{res}"
            if code != 0:
                info = self.color_str(info, "red")
                is_success = False
                if ssh_obj.h not in self.failed_hosts:
                    self.failed_hosts.append(ssh_obj.h)
            else:
                info = self.color_str(info, "lightblue")
            print(info)
        if is_success:
            self.success_hosts.append(ssh_obj.h)
            if ssh_obj.h in self.failed_hosts:
                self.failed_hosts.remove(ssh_obj.h)
 
    def overview(self):
        """展示总的执行结果"""
        for i in self.success_hosts:
            print(self.color_str(i, "lightblue"))
        print("-" * 30)
        for j in self.failed_hosts:
            print(self.color_str(j, "red"))
        info = "Success hosts {}; Failed hosts {}."
        s, f = len(self.success_hosts), len(self.failed_hosts)
        info = self.color_str(info.format(s, f), "green")
        print(info)

    @staticmethod
    def color_str(old, color=None):
        """给字符串添加颜色"""
        if color == "red":
            new = "\033[31;1m{}\033[0m".format(old)
        elif color == "green":
            new = "\033[32;1m{}\033[0m".format(old)
        elif color == "blue":
            new = "\033[34;1m{}\033[0m".format(old)
        elif color == "lightblue":
            new = "\033[36;1m{}\033[0m".format(old)
        else:
            new = old
        return new

if __name__ == '__main__':
    with open ("hosts.txt") as f:
        for line in f:
            h = line.split(',')[0];
            p = line.split(',')[1];
            u = line.split(',')[2];
            w = line.split(',')[3].strip("\n");

            obj = SSHParamiko(h, p, u, w)
            cmds = ["df -h", "ls"]
            all_obj = AllRun([obj], cmds)
            all_obj.concurrent_run()
            all_obj.overview()

原文链接:https://www.cnblogs.com/zingp/p/8930320.html


「 文章如果对你有帮助,请点个赞哦^^ 」 

3+