• python使用paramiko实现ssh定时执行命令


    用这个脚本,我每天12点,通过华为服务器imana 200的ssh,硬重启一次。

    reboot.py -host 192.168.9.240 -u root -p 你的密码 -cmds "ipmcset -d frucontrol -v 0,y"

    原文

    https://www.cnblogs.com/Rosaany/p/16093521.html

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    # @Author: Rosaany
    import functools
    
    from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException
    from argparse import RawTextHelpFormatter
    import paramiko  # 第三方库, pip安装, pip install paramiko -i https://pypi.douban.com/sample
    import time
    import sys
    import argparse
    import socket
    
    
    def g_time(func):
        # 计时装饰器
        def inner(*arg, **kwarg):
            s_time = time.time()
            res = func(*arg, **kwarg)
            e_time = time.time()
            t_time = e_time - s_time
            days = t_time // (24 * 60 * 60)
            t_time %= (24 * 60 * 60)
            hours = t_time // (60 * 60)
            t_time %= (60 * 60)
            minutes = t_time // 60
            t_time %= 60
            seconds = t_time % 60
            print('>>>程序运行时间:{days:.0f}天{hours:.0f}时{minutes:.0f}分{seconds:.0f}秒'.format(days=days, hours=hours,
                                                                                         minutes=minutes, seconds=seconds))
            return res
    
        return inner
    
    
    def retry(exceptions: list, times=3, wait=1):
        """重连机制"""
        if not isinstance(exceptions, (tuple, list)):
            new_exceptions = [exceptions]
        else:
            new_exceptions = exceptions
    
        def inner_retry(func, count, *args, **kwargs):
    
            if count > times:
                return
            try:
                return func(*args, **kwargs)
            except tuple(new_exceptions) as e:
                if count < times:
                    time.sleep(wait)
                    return inner_retry(func, count + 1, *args, **kwargs)
                else:
                    print("重连失败!")  # raise e
    
        def decorator(func):
            @functools.wraps(func)
            def wrapped(*args, **kwargs):
                return inner_retry(func, 0, *args, **kwargs)
    
            return wrapped
    
        return decorator
    
    
    def ssh_connected(ssh, cmds, waits, verbose):
        try:
            # 激活交互式shell
            # https://stackoverflow.com/questions/6203653/how-do-you-execute-multiple-commands-in-a-single-session-in-paramiko-python
            channel = ssh.invoke_shell()
            time.sleep(1)
    
            stop = True
            while stop:
                try:
                    for cmd in cmds:
                        channel.send(cmd.encode())
                        # 模拟回车'Enter'这个动作
                        channel.send(b'\n')
                        # 每个命令间隔时间
                        time.sleep(1)
                        r = channel.recv(40960).decode()
                        if verbose:
                            print(r)
                    # 执行完一轮命令,等待时间
                    time.sleep(waits)
                except KeyboardInterrupt:  # 捕获ctrl + c时终止程序
                    stop = False
    
                if not waits:
                    stop = False
    
            channel.close()
            ssh.close()
        except AttributeError as e:
            raise e
    
    
    @g_time
    @retry([AttributeError, OSError], times=3, wait=3)
    def ssh_client(host: str, user: str, pwd: str, cmds: str, waits: int, verbose: int):
        """ssh客户端"""
    
        # 私钥文件的存放路径
        # private = paramiko.RSAKey.from_private_key_file(r'C:\Users\xxxx\Documents\xxx')
        # 创建一个实例化
        ssh = paramiko.SSHClient()
        # 加载系统SSH密钥
        ssh.load_system_host_keys()
        # 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        # 连接设备
        try:
            ssh.connect(hostname=host, username=user, timeout=5, compress=True, password=pwd  # pkey=private,  #可以采用密钥连接
                        )
    
            print("正在连接主机ip: {}.....".format(host))
        except NoValidConnectionsError:
            print('连接出现了问题')
        except AuthenticationException:
            print('用户名或密码错误')
        except socket.timeout:
            print('请检查你的远程主机通讯连接是否正常')
        except Exception as err:
            print('其他错误问题: {}'.format(err))
        finally:
            ssh_connected(ssh, cmds, waits, verbose)
    
    
    def tool():
        """
        命令行参数
        """
        ssh_client_help = "一个简单的SSH脚本定时执行命令脚本,如想终止脚本,请按下快捷键ctrl+c \n" \
                          "简单的示例:$python sshclient_exec_command.py -cmds 'top, ls, ifconfig'"
    
        if len(sys.argv) == 1:
            sys.argv.append('--help')
    
        parser = argparse.ArgumentParser(description=ssh_client_help, formatter_class=RawTextHelpFormatter)
    
        parser.add_argument('-u', type=str, default='root', help='ssh访问主机的用户名,默认用户名是root')
        parser.add_argument('-p', type=str, default='root', help='ssh访问主机的密码,默认密码是root')
        parser.add_argument('-host', type=str, default='192.168.1.248', help='ssh访问主机ip,默认访问主机是192.168.1.248')
        parser.add_argument('-cmds', type=str, default="ls -ll, ifconfig",
                            help='执行输入的命令,多个以英文逗号分隔,默认输入命令是"ls -ll,ifconfig"')
        parser.add_argument('-t', type=str, default=0, help='输入一个定时等待时间,单位是秒,默认定时时间为0秒')
        parser.add_argument('-v', type=int, default=1, help='显示详细信息,默认输出详细信息')
    
        arguments = parser.parse_args()
        return arguments
    
    
    def main():
        """主程序"""
        arguments = tool()
        host = arguments.host
        user = arguments.u
        pwd = arguments.p
        cmds = arguments.cmds
        verbose = arguments.v
        waits = arguments.t
    
        if not isinstance(verbose, int):
            verbose = int(verbose)
    
        if not isinstance(waits, int):
            waits = int(waits)
    
        if isinstance(cmds, str):
            cmds = cmds.split(',')
    
        print("执行命令:{cmd}".format(cmd=cmds))
    
        ssh_client(host=host, user=user, pwd=pwd, cmds=cmds, verbose=verbose, waits=waits)
    
    
    if __name__ == '__main__':
        # linux实时查看ssh连接通道state变化,-n 1表示每一秒查询一遍,注意TCP四次挥手是否正常释放
        # watch -n 1 -d 'netstat -anlt | grep 192.168.1.1'
        main()
    

      

    使用示例

    shell
    $python .\sshclient_exec_commands.py
    usage: sshclient_exec_commands.py [-h] [-u U] [-p P] [-host HOST] [-cmds CMDS] [-t T] [-v V]
    
    一个简单的SSH脚本定时执行命令脚本,如想终止脚本,请按下快捷键ctrl+c
    简单的示例:$python sshclient_exec_command.py -cmds 'top, ls, ifconfig'
    
    optional arguments:
      -h, --help  show this help message and exit
      -u U        ssh访问主机的用户名,默认用户名是root
      -p P        ssh访问主机的密码,默认密码是123456
      -host HOST  ssh访问主机ip,默认访问主机是192.168.1.1
      -cmds CMDS  执行输入的命令,多个以英文逗号分隔,默认输入命令是"ls -ll,ifconfig"
      -t T        输入一个定时等待时间,单位是秒,默认定时时间为0秒
      -v V        显示详细信息,默认输出详细信息
    • 定时执行

    加上-t参数,默认不执行定时,单位是秒
    解释:ssh连接主机192.168.1.1,用户名root密码123456,在当前用户目录下每秒输入一次“ls”命令。

    python .\sshclient_exec_commands.py -host 192.168.1.1 -u root -p 123456 -cmds "ls" -t 1

    • 执行多个命令

    比如:-cmds "ls -l, ifconfig",多个命令,中间加入一个英文逗号
    python .\sshclient_exec_commands.py -host 192.168.1.1 -u root -p 123456 -cmds "ls -l, ifconfig" -t 1

     
  • 相关阅读:
    Linux 文本处理工具
    which, whereis, locate, find
    Linux source
    Linux 环境变量
    Linux shell
    spring通过在web.xml中配置ContextLoaderListener来加载spring context配置文件和在DispatcherServlet中也可以来加载spring context配置文件,有什么区别?
    JAVA在线学习优质网站
    java实现AES加解密
    Mybatis Puls @Select() 查询结果映射为Map为null的坑
    springboot自带maven插件打包的jar可以被别的springboot项目引用但不能正确使用
  • 原文地址:https://www.cnblogs.com/itfat/p/16734164.html
Copyright © 2020-2023  润新知