原文
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
标签:help,python,cmds,60,host,ssh,time,paramiko
From: https://www.cnblogs.com/itfat/p/16734164.html