paramiko 跳转登录sftp
当不能直连sftp的时候,需要先登录到跳板机才能连接目标sftp的时候,适用此种情况
1 import paramiko 2 import re 3 import time 4 import os 5 import colorama 6 7 hosts = ['IP1','IP2'] 8 hostNames = {hosts[0]:"跳板机",hosts[1]:"跳板机"} 9 passwords = {hosts[0]:"Admin_12312312",hosts[1]:"Admin_12345616"} 10 users = {hosts[0]:"admin",hosts[1]:"admin"} 11 12 errInfoFileList={} #用于在同一次运行中保持文件名相同 13 outInfoFileList={} #用于在同一次运行中保持文件名相同 14 15 def my_exec_command(SSHClient__,commandString,getPty=False): 16 ''' 17 进行了一次错误捕捉,仍然返回三个经典参数 18 get_pty:是否保持终端 19 ''' 20 try: 21 stdin, stdout, stderr = SSHClient__.exec_command(commandString,get_pty = getPty) 22 except Exception as errMsg: 23 print("虽然exec_command报错了,但是不需要管他.") 24 print("这是报错信息:") 25 print("{}: {}".format(Exception,errMsg)) 26 return stdin, stdout, stderr 27 28 def isError(stdErr): 29 ''' 30 检查命令的输出有没有错误信息,有返回True,和错误信息(string 类型),没有返回False和None 31 请传入stderr,而不是stdin或者stdout 32 ''' 33 errStr = stdErr.read().decode() 34 if len(errStr) == 0: 35 return False,None 36 else: 37 return True,errStr 38 39 def errInfoToFile(host,errinfo,commandString): 40 ''' 41 用于将命令执行过程中的错误信息保存下来,在当前路径 42 ''' 43 if host not in errInfoFileList: 44 currentTime = time.localtime() 45 fileTime=str(currentTime.tm_year) + "年" + str(currentTime.tm_mon) + "月" + str(currentTime.tm_mday) + "日" + str(currentTime.tm_hour) + "时" + str(currentTime.tm_min) + "分" 46 fileName = re.sub(r':|\.','-',host) + '_commandErrorLog_{}.txt'.format(fileTime) 47 errInfoFileList[host] = fileName 48 with open(fileName,'a',encoding= 'UTF8',newline='') as errFile: 49 print("命令:{} 的错误信息".format(commandString),file=errFile) 50 print(errinfo,file=errFile,end='') 51 print('',file=errFile) 52 else: 53 fileName = errInfoFileList[host] 54 errInfoFileList[host] = fileName 55 with open(fileName,'a',encoding= 'UTF8',newline='') as errFile: 56 print("命令:{} 的错误信息:".format(commandString),file=errFile) 57 print(errinfo,file=errFile,end='') 58 print('',file=errFile) 59 60 def outInfoToFile(host,outinfo,commandString): 61 ''' 62 用于将命令执行过程中的输出信息保存下来, 63 在脚本运行的路径下,而不是脚本所在的位置 64 ''' 65 if host not in outInfoFileList: 66 currentTime = time.localtime() 67 fileTime=str(currentTime.tm_year) + "年" + str(currentTime.tm_mon) + "月" + str(currentTime.tm_mday) + "日" + str(currentTime.tm_hour) + "时" + str(currentTime.tm_min) + "分" 68 fileName = re.sub(r':|\.','-',host) + '_commandOutLog_{}.txt'.format(fileTime) 69 outInfoFileList[host] = fileName 70 with open(fileName,'a',encoding= 'UTF8',newline='') as outFile: 71 print("命令:{} 的输出信息:".format(commandString),file=outFile) 72 print(outinfo,file=outFile,end='') 73 print('',file=outFile) 74 else: 75 fileName = outInfoFileList[host] 76 outInfoFileList[host] = fileName 77 with open(fileName,'a',encoding= 'UTF8',newline='') as outFile: 78 print("命令:{} 的输出信息:".format(commandString),file=outFile) 79 print(outinfo,file=outFile,end='') 80 print('',file=outFile) 81 82 def ParsingTheOutput(rst,label): 83 ''' 84 解析输出,使用channel.recv读取的数据需要做二次解析和判断: 85 b'ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/1\r\n/home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/1/20210126110000_BASICCM_e53d309d_66c0_4787_b7b5_ad357ee2853d.zip\r\nsftp> ' 86 ''' 87 currentTime = time.localtime() 88 mon = str(currentTime.tm_mon) 89 if len(mon) == 1: 90 mon = '0' + mon 91 day = str(currentTime.tm_mday) 92 if label == "主用BBB-受理日志": 93 day = str(int(day) - 1) 94 if len(day) == 1: 95 day = '0' + day 96 dataStr1 = str(currentTime.tm_year) + mon + day 97 dataStr2 = str(currentTime.tm_year) + '-' + mon + '-' + day 98 if -1 != rst.find(dataStr1): 99 print("数据:{} 存在。".format(label)) 100 else: 101 if -1 != rst.find(dataStr2): 102 print("数据:{} 存在。".format(label)) 103 else: 104 print(rst) 105 print("dataStr1:{}\t dataStr2:{}".format(dataStr1,dataStr2)) 106 print("\033[0;31;40m\t数据:{} 不存在。\033[0m".format(label)) 107 108 def main(): 109 commandList = { 110 hosts[0]:[["sftp -P 10004 XYbackup2@10.100.17.67\n\n","XYAAA@123\n"], #sftp登录 111 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/1\n","主用AAA-配置文件1"], 112 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/2\n","主用AAA-配置文件2"], 113 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/3\n","主用AAA-配置文件3"], 114 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/4\n","主用AAA-配置文件4"], 115 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/5\n","主用AAA-配置文件5"], 116 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/XTSJ/6\n","主用AAA-配置文件6"], 117 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/1\n","主用BBB-配置文件1"], 118 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/2\n","主用BBB-配置文件2"], 119 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/3\n","主用BBB-配置文件3"], 120 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/4\n","主用BBB-配置文件4"], 121 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/5\n","主用BBB-配置文件5"], 122 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/XTSJ/6\n","主用BBB-配置文件6"], 123 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/1\n","备用AAA-配置文件1"], 124 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/2\n","备用AAA-配置文件2"], 125 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/3\n","备用AAA-配置文件3"], 126 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/4\n","备用AAA-配置文件4"], 127 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/5\n","备用AAA-配置文件5"], 128 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/XTSJ/6\n","备用AAA-配置文件6"], 129 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/1\n","备用BBB-配置文件1"], 130 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/2\n","备用BBB-配置文件2"], 131 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/3\n","备用BBB-配置文件3"], 132 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/4\n","备用BBB-配置文件4"], 133 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/5\n","备用BBB-配置文件5"], 134 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/XTSJ/6\n","备用BBB-配置文件6"], 135 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/RZSJ\n","主用BBB-受理日志"], #该“主用BBB-受理日志”作为一个检查项,若需更改,需要同步更改ParsingTheOutput函数关于day变量的更改 136 ["ls /home/XYbackup2/AAA/ABCDEFAAA003AAA001BXY/CMDLOG\n","主用AAA-操作日志"], 137 ["ls /home/XYbackup2/AAA/ABCDEFAAA003UBBB001BXY/CMDLOG\n","主用BBB-操作日志"], 138 ["ls /home/XYbackup2/AAA/XBXAscAAA003AAA000BXY/CMDLOG\n","备用AAA-操作日志"], 139 ["ls /home/XYbackup2/AAA/XBXAscAAA003UBBB002BXY/CMDLOG\n","备用BBB-操作日志"], 140 ], 141 hosts[1]:[["sftp -P 10004 XYbackup@10.200.17.67\n","XY*#123\n"], #sftp登录 142 ["ls /backup/ftphome/BACKUP/XY/AAA/ABCDEFAAA003UBBB001BXY/YHSJ/bureau_91\n","主用BBB-用户数据"], 143 ["ls /backup/ftphome/BACKUP/XY/AAA/XBXAscAAA003UBBB002BXY/YHSJ/bureau_121\n","备用BBB-用户数据"], 144 ]} 145 ssh = paramiko.SSHClient() 146 #若主机之前未连接过,自动选择yes添加到本地know_hosts文件 147 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 148 for host in hosts: 149 try: 150 ssh.connect(host,username=users[host],password=passwords[host],timeout=10) 151 except Exception as msg: 152 print("主机 “{}” 连接超时,信息:{}。".format(host,msg)) 153 continue 154 #↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓核心代码############################################ 155 channel = ssh.invoke_shell() 156 channel.send(commandList[host][0][0]) 157 time.sleep(2) 158 channel.send(commandList[host][0][1]) 159 time.sleep(2) 160 rst = str(channel.recv(1024).decode('utf-8')) #读取即清除 161 for command in commandList[host][1:]: 162 channel.send(command[0]) 163 time.sleep(2) 164 rst = str(channel.recv(10240).decode('utf-8')) 165 outInfoToFile(host,rst,command[0]) 166 ParsingTheOutput(rst,command[1]) 167 ssh.close() 168 main()