diff --git a/connect.py b/connect.py index 8cc087e1f..00a826de0 100644 --- a/connect.py +++ b/connect.py @@ -72,8 +72,7 @@ class Tty(object): self.vim_flag = False self.ps1_pattern = re.compile('\[.*@.*\][\$#]') self.vim_data = '' - - + @staticmethod def is_output(strings): newline_char = ['\n', '\r', '\r\n'] @@ -81,46 +80,15 @@ class Tty(object): if char in strings: return True return False - - - def remove_obstruct_char(cmd_str): - '''删除一些干扰的特殊符号''' - control_char = re.compile(r'\x07 | \x1b\[1P | \r ', re.X) - cmd_str = control_char.sub('',cmd_str.strip()) - patch_char = re.compile('\x08\x1b\[C') #删除方向左右一起的按键 - while patch_char.search(cmd_str): - cmd_str = patch_char.sub('', cmd_str.rstrip()) - return cmd_str - - - def remove_control_char(result_command): - """ - 处理日志特殊字符 - """ - control_char = re.compile(r""" - \x1b[ #%()*+\-.\/]. | - \r | #匹配 回车符(CR) - (?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd - (?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL) - (?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST) - \x1b. #匹配 转义过后的字符 - [\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符 - """, re.X) - result_command = control_char.sub('', result_command.strip()) - global VIM_FLAG - if not VIM_FLAG: - if result_command.startswith('vi') or result_command.startswith('fg'): - VIM_FLAG = True - return result_command.decode('utf8',"ignore") - else: - return '' - def deal_command(self, str_r): """ 处理命令中特殊字符 """ - str_r = self.remove_obstruct_char(str_r) + str_r = re.sub('\x07', '', str_r) # 删除响铃 + patch_char = re.compile('\x08\x1b\[C') # 删除方向左右一起的按键 + while patch_char.search(str_r): + str_r = patch_char.sub('', str_r.rstrip()) result_command = '' # 最后的结果 backspace_num = 0 # 光标移动的个数 @@ -129,15 +97,16 @@ class Tty(object): while str_r: tmp = re.match(r'\s*\w+\s*', str_r) if tmp: - str_r = str_r[len(str(tmp.group(0))):] if reach_backspace_flag: pattern_str += str(tmp.group(0)) + str_r = str_r[len(str(tmp.group(0))):] continue else: result_command += str(tmp.group(0)) + str_r = str_r[len(str(tmp.group(0))):] continue - tmp = re.match(r'\x1b\[K[\x08]*', str_r) #处理删除确认符号,删除退格确认之前的数据,当结果队列不够删除时,则将临时队列中的加上一起删除 + tmp = re.match(r'\x1b\[K[\x08]*', str_r) if tmp: if backspace_num > 0: if backspace_num > len(result_command): @@ -155,12 +124,12 @@ class Tty(object): str_r = str_r[len(str(tmp.group(0))):] continue - tmp = re.match(r'\x08+', str_r) #处理退格符号,第一次碰到则记下,第二次碰到则进行删除操作,如果退格符在最后则不计 + tmp = re.match(r'\x08+', str_r) if tmp: str_r = str_r[len(str(tmp.group(0))):] if len(str_r) != 0: if reach_backspace_flag: - result_command = result_command[0:-backspace_num] + pattern_str + result_command = result_command[0:-backspace_num] + pattern_str pattern_str = '' else: reach_backspace_flag = True @@ -168,32 +137,32 @@ class Tty(object): continue else: break - - tmp = re.match(r'(\x1b\[1@\w)+', str_r) #处理替换的命令 - if tmp: - str_lists = re.findall(r'(?<=\x1b\[1@)\w',str(tmp.group(0))) - tmp_str =''.join(str_lists) - result_command_list = list(result_command) - if len(tmp_str) > 1: - result_command_list[-backspace_num:-(backspace_num-len(tmp_str))] = tmp_str - elif len(tmp_str) > 0: - result_command_list.insert(-backspace_num, tmp_str) - result_command = ''.join(result_command_list) - str_r = str_r[len(str(tmp.group(0))):] - backspace_num = 0 - continue - if reach_backspace_flag: #处理其他没有匹配的字符 + if reach_backspace_flag: pattern_str += str_r[0] else: result_command += str_r[0] str_r = str_r[1:] - if backspace_num > 0: #处理最后的退格符号 + if backspace_num > 0: result_command = result_command[0:-backspace_num] + pattern_str - result_command = self.remove_control_char(result_command) - return result_command + control_char = re.compile(r""" + \x1b[ #%()*+\-.\/]. | + \r | #匹配 回车符(CR) + (?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd + (?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL) + (?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST) + \x1b. #匹配 转义过后的字符 + [\x80-\x9f] | (?:\x1b\]0.*) | \[.*@.*\][\$#] | (.*mysql>.*) #匹配 所有控制字符 + """, re.X) + result_command = control_char.sub('', result_command.strip()) + if not self.vim_flag: + if result_command.startswith('vi') or result_command.startswith('fg'): + self.vim_flag = True + return result_command.decode('utf8', "ignore") + else: + return '' def get_log(self): """ @@ -292,48 +261,6 @@ class Tty(object): else: self.ssh = ssh return ssh - - def get_connect2(self): - connect_info = self.get_connect_info() - try: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((connect_info.get('ip'), connect_info.get('port'))) - except Exception as e: - raise ServerError('连接失败: ' + str(e)) - - try: - transport = paramiko.Transport(sock) - try: - transport.start_client() - except paramiko.SSHException: - raise ServerError('ssh 协商失败.') - - role_key = connect_info.get('role_key') - if role_key and os.path.isfile(role_key): - mykey=paramiko.RSAKey.from_private_key_file(filename=role_key) - transport.auth_publickey(connect_info.get('role_name'), mykey) - else: - transport.auth_password(connect_info.get('role_name'), connect_info.get('role_pass')) - if not transport.is_authenticated(): - raise ServerError('认证失败') - - transport.set_keepalive(30) - transport.use_compression(True) - channel = transport.open_session() - channel.get_pty() - channel.invoke_shell() - win_size = self.get_win_size() - channel.resize_pty(height=win_size[0], width=win_size[1]) - self.channel = channel - return self.channel - except Exception as e: - raise ServerError('*** Caught exception:' + str(e)) - try: - transport.close() - except: - pass - sys.exit(1) - class SshTty(Tty): @@ -462,7 +389,18 @@ class SshTty(Tty): except: pass - channel.send('TERM=xterm;clear\n') + # 设置PS1并提示 Set PS1 and msg it + #channel.send(ps1) + #channel.send(login_msg) + # channel.send('echo ${SSH_TTY}\n') + # global SSH_TTY + # while not channel.recv_ready(): + # time.sleep(1) + # tmp = channel.recv(1024) + #print 'ok'+tmp+'ok' + # SSH_TTY = re.search(r'(?<=/dev/).*', tmp).group().strip() + # SSH_TTY = '' + # channel.send('clear\n') # Make ssh interactive tunnel self.posix_shell() @@ -672,5 +610,3 @@ def main(): if __name__ == '__main__': main() - -