热心冰块
作者热心冰块·2022-01-26 14:40
项目经理·浪潮INSPUR

Python3的SSH模块Paramiko用法3——登陆信息外置到文件

字数 3468阅读 746评论 0赞 0

在用法2中我们主要实现了用类封装了Paramiko,但登陆信息还是写死在CONN_Info变量中了,本文将尝试将登陆信息单独放到文件:LoginInfo.ini中,并在Python代码中实现顺序批量登陆,具体代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-


import paramiko
import paramiko.util


class SSHTransport(object):
    def __init__(self, host, port, username, password):
        self._host = host
        self._port = port
        self._username = username
        self._password = password

        self._transport = None
        self._sftp = None
        self._client = None

        self._connect()

    def _connect(self):
        paramiko.util.log_to_file("D:\\SSH_Connect.log")
        transport = paramiko.Transport((self._host, self._port))
        transport.connect(username=self._username, password=self._password)
        self._transport = transport

    def download(self, remotepath, localpath):
        if self._sftp is None:
            self._sftp = paramiko.SFTPClient.from_transport(self._transport)
        self._sftp.get(remotepath, localpath)

    def upload(self, localpath, remotepath):
        if self._sftp is None:
            self._sftp = paramiko.SFTPClient.from_transport(self._transport)
        self._sftp.put(localpath, remotepath)

    def exec_command(self, command):
        if self._client is None:
            self._client = paramiko.SSHClient()
            self._client._transport = self._transport
        stdin, stdout, stderr = self._client.exec_command(command)
        for Line in stdout.readlines():
            print(Line, end="")

    def close(self):
        if self._transport:
            self._transport.close()
        if self._client:
            self._client.close()


def login_info(file_name):
    login_info = list()
    host_info = list()
    with open(file_name, "r")as f:
        for Line in f.read().splitlines():
            match len(host_info):
                case 0:
                    host_info.append(Line)
                case 1:
                    host_info.append(int(Line))
                case 2:
                    host_info.append(Line)
                case 3:
                    host_info.append(Line)
                    login_info.append(host_info)
                    host_info = list()
            # if len(host_info) == 4:
            #     host_info = list()
            #     continue
            # elif len(host_info) == 3:
            #     host_info.append(Line)
            #     login_info.append(host_info)
            # else:
            #     host_info.append(Line)
        print(login_info)
        return login_info


if __name__ == "__main__":
    for host_info in login_info("LoginInfo.ini"):
        conn = SSHTransport(host_info[0], host_info[1], host_info[2], host_info[3])
        #localpath = "test.py"
        #remotepath = "/home/ice/test.py"
        #conn.upload(localpath, remotepath)
        conn.exec_command("ls -l")
        #conn.download(remotepath, "testtest.py")

其中函数login_info实现了登陆文件的加载,并将登陆信息整理成二维List类型数据,用For循环遍历每条登陆信息,其中0~3位置的元素分别存储着IP,PORT,USERNAME,PASSWORD,这里为了方便测试仅用了SSHTransport类的exec_command方法。
下面是LoginInfo.ini的文件内容:

172.26.32.139
22
ice
tomorange
172.26.32.139
22
ice
tomorange

每4行为一条完整的登陆信息,4N+1为:IP,4N+2为:Port,4N+3为:Username,4N+4为:Password
这里我偷懒了,没写命令也从文件中读取,并且区分动作是:command、upload、download等,有人感兴趣可以完善下代码哈,我就不写了,和LoginInfo的实现方法一样,只是会在区分动作上用点不一样的,也都非常好实现。
接下来我将写一写多进程方面的东西,从而实现多设备并发登陆,之前用多线程写过类似的东西,并发量的增加对总执行时间的影响基本不大,总运行时间基本维持在1~1.5个设备顺序运行的时间。
注意:这里我的运行环境是3.10.1,比较新的版本,所以我的代码中login_info函数用了match——case语句,这是新版本才有的分支语句,老版本只能用if——elif语句来实现。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广