背景

目前在做的某个项目有这么一个需求:ups电源在市电断开时,会通过串口发送一个数据给到电脑(win10系统),该电脑在收到该信号后,需要远程将在同一网段的两个服务器及时关掉。
服务器都是linux系统(Ubuntu、centos),都已经开启了ssh,且都已经知道他们的账号和密码。

查找到的资料

1.先进行免密登录,然后执行指令

免密登录
https://zhuanlan.zhihu.com/p/401327519

关机指令
https://blog.csdn.net/weixin_33349121/article/details/116867532
https://blog.csdn.net/weixin_39587238/article/details/116808778

“ssh –l user remotehost sudo shutdown –h now”
因为这个办法需要搞公钥密钥,又要在服务器上传文件之类的,比较麻烦。所以没选用这个办法

2.VBS脚本指令

https://blog.csdn.net/qq_43391414/article/details/120575748
一个相对简单的办法.。但是从评论区看到,他们说会因为中文输入法的问题导致错误。所以我这边也还是没用到这个办法

3.python脚本1

https://blog.csdn.net/junbujianwpl/article/details/52901862
这个脚本中用到了 pexpect,在windows下会无法使用其spawn函数。因此我这边也没采用这种方式。

4.python脚本2

https://blog.csdn.net/xiaoxin_OK/article/details/119783073
这个完全解决了问题,但是需要安装python以及paramiko。但是我这边是可以接受的,用的是这种办法。

import paramiko


class SshClass:
    """
    ssh连接对象
    本对象提供了密钥连接、密码连接、命令执行、关闭连接
    """
    ip = ''
    port = 22
    username = ''
    timeout = 0
    ssh = None

    def __init__(self, ip, username, port=22, timeout=30):
        """
        初始化ssh对象
        :param ip: str  主机IP
        :param username: str  登录用户名
        :param port: int  ssh端口
        :param timeout: int  连接超时
        """
        self.ip = ip
        self.username = username
        self.port = port
        self.timeout = timeout
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh = ssh

    def conn_by_key(self, key):
        """
        密钥连接
        :param key: str  rsa密钥路径
        :return: ssh连接对象
        """
        rsa_key = paramiko.RSAKey.from_private_key_file(key)
        self.ssh.connect(hostname=self.ip, port=self.port, username=self.username, pkey=rsa_key, timeout=self.timeout)
        if self.ssh:
            print("密钥连接成功.")
        else:
            self.close()
            raise Exception("密钥连接失败.")

    def conn_by_pwd(self, pwd):
        """
        密码连接
        :param pwd: str  登录密码
        :return: ssh连接对象
        """
        self.ssh.connect(hostname=self.ip, port=self.port, username=self.username, password=pwd)
        if self.ssh:
            print("密码连接成功.")
        else:
            self.close()
            raise Exception("密码连接失败.")

    def exec_command(self, command):
        """
        命令控制
        :param command: str  命令
        :return: dict  命令执行的返回结果
        """
        if command:
            stdin, stdout, stderr = self.ssh.exec_command(command)
            return {
                "stdin": command,
                "stdout": stdout.read(),
                "stderr": stderr.read()
            }
        else:
            self.close()
            raise Exception("命令不能为空字符串.")

    def close(self):
        """
        关闭当前连接
        :return:
        """
        if self.ssh:
            self.ssh.close()
        else:
            raise Exception("ssh关闭失败,当前对象并没有ssh连接.")


if __name__ == '__main__':
    SSH = SshClass("111.111.6.115", "root", port=22)
    SSH.conn_by_pwd("123456")
    print(SSH.exec_command("ls"))

最终采纳

目前使用的是第4种方式。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐