import re
import time
import paramiko
import logging
logging.basicConfig(level=logging.NOTSET, format='[%(filename)s:%(lineno)d]-%(levelname)s %(message)s')
class CSSH():
def __init__(self):
self.wait_s = 10
# 服务器信息
host = 'host ip'
port = 22
username = 'user name'
password = 'password'
self.cmd_log = open('./ssh_log.txt', 'w+', encoding='utf-8') # 记录日志
try:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(hostname=host, port=port, username=username, password=password)
except paramiko.AuthenticationException:
print("认证失败,请检查用户名和密码。")
except paramiko.SSHException as ssh_ex:
print(f"SSH连接出现错误: {str(ssh_ex)}")
except Exception as ex:
print(f"出现未知错误: {str(ex)}")
def ssh_save_log_to_file(self, output):
lines = output.splitlines()
non_empty_lines = [line for line in lines if line.strip()]
output = '\n'.join(non_empty_lines)
self.cmd_log.write(output)
def ssh_read_output(self):
timeout = self.wait_s
start_time = time.time()
output = ''
prompt = '$' # 结束符
while True: # 等待结束符或者超时退出
if self.shell.recv_ready():
data = self.shell.recv(65535).decode('utf-8')
output += data
start_time = time.time()
if time.time() - start_time > timeout:
break
if output.endswith(prompt):
break
# 匹配所有ANSI转义字符的正则表达式
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
output = ansi_escape.sub('', output)
self.ssh_save_log_to_file(output)
return output
def ssh_execute_command(self):
self.shell = self.ssh.invoke_shell() # 打开交互式 shell
self.shell.send('ls -al\n')
time.sleep(2)
self.ssh_read_output()
def ssh_close(self):
self.cmd_log.close()
self.ssh.close()
if __name__ == '__main__':
c_ssh = CSSH()
c_ssh.ssh_execute_command()
c_ssh.ssh_close()