一、通过paramiko实现SSH远程登录服务器、执行命令并返回信息;

二、通过wxpython实现UI化;

三、代码实现如下:

1)主程序MainUI

#coding:utf8
#!/usr/bin/env python
#@author: 9527
import wx
from MainFrameUI import MainFrameUI#子类化wxpython应用程序
#定义wx.App的子类
class MainApp(wx.App):
#@author: 9527
#定义一个应用程序的初始化方法
def OnInit(self):
#启动主程序 #创建一个MainFrame的实例
win = MainFrameUI(None)
#设置窗口的尺寸800*638
win.SetSize((1100, 800))
#设置窗体放置在屏幕中心
win.CenterOnScreen()
#显示或隐藏窗口(Frame框架可见)。其中的参数可以为 True 或False。
#frame.Hide() # 等同于frame.Show(False)
win.Show(show = True)
#设计为应用程序的顶级窗口,此处即将win设计为顶级窗口
self.SetTopWindow(win) return True if __name__ == "__main__":#创建wx.App子类(MainApp)的实例,实例化
#这行创建了应用程序对象。这行之后,所有发送到stderr或stdout的文本
#都可被wxPython重定向到一个框架。参数redirect=True决定了是否重定向。
#如果值为True,则重定向到框架,如果值为False,则输出到控制台。
app = MainApp()
#应用程序进入消息循环
app.MainLoop()

2)UI框架MainFrameUI

#coding:UTF-8
#!/usr/bin/env python
#author by No9527
import wx
import PicturepackageUI
import MultipleEffectiveServerResourceMonitorUI as MESRM
from threading import Thread
import queue class MainFrameUI(wx.Frame):
#@author: 9527
def __init__(self,parent):
wx.Frame.__init__(self,parent,-1,title="服务器资源监控",pos=wx.DefaultPosition,
style=wx.SIMPLE_BORDER|wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX) self.Ssh_load = None
#定义信息列表
self.Info_List = []
self.Info_List2= [] #设置程序最小化图标
self.SetIcon(PicturepackageUI.monitor_png.GetIcon()) #绑定工具按钮与对应事件
self.action_or_stop = True #初始化循环为真 #消息定义队列
self.QueueInfo = queue.Queue(100000) #********************************************************************************* #设置panel面板1
self.panel1 = wx.Panel(self,pos=(-1,40),size=(1100,120))
self.panel1.SetBackgroundColour("#33cccc") #主机IP地址
self.IP_Addr0 = wx.StaticText(self.panel1, label="主机IP地址", pos=(10, 34))
# 单行文本输入框(加了验证器)
self.IP_Addr1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY,
pos=(75, 30), size=(150, -1))
#用户名
self.UserName0 = wx.StaticText(self.panel1, label="用户名", pos=(240, 34))
self.UserName1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY,
pos=(280, 30), size=(150, -1))
#密码
self.password0 = wx.StaticText(self.panel1, label="登录密码", pos=(440, 34))
# 密码输入框
self.password1 = wx.TextCtrl(self.panel1, id=wx.ID_ANY, style=wx.TE_PASSWORD,
pos=(490, 30), size=(150, -1)) #命令
self.command0 = wx.StaticText(self.panel1, label="sar命令", pos=(650, 34))
# 密码输入框
self.command1 = wx.TextCtrl(self.panel1,value="sar -n DEV 5 -u -r", id=wx.ID_ANY,
pos=(695, 30), size=(150, -1)) #确定按钮
self.ok_btn = wx.Button(self.panel1, -1, "添加", pos=(75,80),size=(70, 20))
#取消按钮
self.cancel_btn = wx.Button(self.panel1, -1, "清空", pos=(165,80),size=(70, 20)) #********************************************************************************* #设置panel面板2
self.panel2 = wx.Panel(self,pos=(-1,150),size=(1100,200))
self.panel2.SetBackgroundColour("#ff9966") CommandInfo0=["sar命令用法: sar [ 选项 ] [ <时间间隔> [ <次数> ] ]",
"主选项和报告:",
"-b I/O 和传输速率信息状况",
"-B 分页状况",
"-d 块设备状况",
"-I { <中断> | SUM | ALL | XALL } 中断信息状况",
"-m 电源管理信息状况",
"-n { <关键词> [,...] | ALL } 网络统计信息",
"关键词可以是:",
"DEV 网卡信息统计",
"EDEV 网卡的错误统计",
"NFS NFS客户端",
"NFSD NFS服务器",
"SOCK Sockets (IPV4套接字)",
"IP IP流(IPV4)",
"EIP IP流的错误统计(IPV4)",
"ICMP ICMP流(IPV4)",
"EICMP ICMP流的错误统计(IPV4)",
"TCP TCP流(IPV4)",
"ETCP TCP流的错误统计(IPV4)",
"UDP UDP流(IPV4)",
"SOCK6 Sockets(IPV6套接字)",
"IP6 IP流(IPV6)",
"EIP6 IP流的错误统计(IPV6)",
"ICMP6 ICMP流(IPV6)",
"EICMP6 ICMP流的错误统计 (IPV6)",
"UDP6 UDP流(IPV6) ",
"-q 队列长度和平均负载",
"-r 内存利用率",
"-R 内存状况",
"-S 交换空间利用率",
"-u [ ALL ]",
"CPU 利用率",
"-v Kernel table 状况",
"-w 任务创建与系统转换统计信息",
"-W 交换信息",
"-y TTY 设备状况",
"-o {<文件路径>}"] #加入换行符链接
CommandInfo1 = "\n".join(CommandInfo0)
#设置命令提示文本框
self.CommandInfoTip = wx.StaticText(self.panel2, label="sar监测命令帮助", pos=(565, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.CommandInfoTip.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL))
self.CommandInfo = wx.TextCtrl(self.panel2,value=CommandInfo1,pos=(565, 45),size = (490,150),
style = wx.TE_READONLY|wx.TE_MULTILINE) # 用户名与密码显示区,内容通过后续在OnButtonClick中调用SetLabel实现 self.up_monitor = wx.StaticText(self.panel2, label="当前登录信息", pos=(30, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.up_monitor.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.up_monitor = wx.TextCtrl(self.panel2,value="登录信息显示在这里",pos=(30, 45),size = (490,150),
style = wx.TE_READONLY|wx.TE_MULTILINE) # 控件与事件绑定在一起
self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.ok_btn)
self.Bind(wx.EVT_BUTTON, self.OnButtonClick, self.cancel_btn)
#********************************************************************************** #设置panel面板3
self.panel3 = wx.Panel(self,pos=(-1,350),size=(1100,450))
self.panel3.SetBackgroundColour("#00cc99") # 设置log信息显示面板 self.log_info0 = wx.StaticText(self.panel3, label="log信息显示区", pos=(30, 15),size = (480,50),
style = wx.ALIGN_CENTRE_HORIZONTAL)
self.log_info0.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.log_info1= wx.TextCtrl(self.panel3,value="log信息显示在这里",pos=(30, 45),size = (1020,300),
style = wx.TE_READONLY|wx.TE_MULTILINE) #启用线程间信息传递及文本框显示线程
msd = Thread(target=self.LogInfodisplay)
msd.setDaemon(1)
msd.start() #********************************************************************************** #设置状态栏及图标工具栏
statusBar = self.CreateStatusBar()#创建状态栏,放置在框架的底部
toolbar = self.CreateToolBar()#创建工具栏,被自动放置在框架的顶部 self.Action = toolbar.AddSimpleTool(wx.NewId(),PicturepackageUI.find_png.getBitmap(),
"开始监控","点击开始服务器监控")#给工具栏增加一个工具
self.Stop=toolbar.AddSimpleTool(wx.NewId(),PicturepackageUI.Lock_png.getBitmap(),
"停止监控","停止当前监控任务")#给工具栏增加一个工具 #绑定HD图标为开始按钮
self.Bind(wx.EVT_TOOL,self.ActionMonitor,self.Action)
#绑定o图标为停止按钮
self.Bind(wx.EVT_TOOL, self.ChangeLoopParameter,self.Stop) toolbar.Realize()#实现显示工具栏 #**************************************************************************************
#函数集中定义区
#************************************************************************************** #定义开始按钮事件,开始监控线程
def ActionMonitor(self,event):
#@author: 9527
self.action_or_stop = True
event.Skip()
td = Thread(target=self.ServerMonitor)
td.setDaemon(1)
td.start() #点击按钮获取输入值
def OnButtonClick(self, event):
#@author: 9527 Display_List=[] if event.GetEventObject() == self.ok_btn:
print("确定")
if self.IP_Addr1.GetValue() == '':
wx.MessageBox("主机IP为空,请输入用户名,再继续......", "提示")
elif self.UserName1.GetValue() == '':
wx.MessageBox("用户名为空,请输入用户名,再继续......", "提示")
elif self.password1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示")
elif self.command1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示") else: if self.Info_List == [] :
#写入列表
self.Info_List.append(self.IP_Addr1.GetValue())
self.Info_List.append(self.UserName1.GetValue())
self.Info_List.append(self.password1.GetValue())
self.Info_List.append(self.command1.GetValue())
self.Info_List2.append(self.Info_List)
self.Info_List = []
else:
#清空列表
self.Info_List.clear()
for A1 in self.Info_List2 :
B1 = ['','','']
B1[0] = '主机IP:' + A1[0]
B1[1] = '用户名:' + A1[1] + ' '
B1[2] = '命令:' + A1[3] + ' ' Display_List.append("\n".join(B1)) #显示到面板panel2的“当前登录信息”
self.up_monitor.SetLabel("\n".join(Display_List)) if event.GetEventObject() == self.cancel_btn:
self.Info_List=[]
self.Info_List2.clear()
print("清空")
if self.IP_Addr1.GetValue() == '':
wx.MessageBox("IP地址,请输入用户名,再继续......", "提示")
elif self.UserName1.GetValue() == '':
wx.MessageBox("用户名为空,请输入密码,再继续......", "提示")
elif self.password1.GetValue() == '':
wx.MessageBox("密码为空,请输入密码,再继续......", "提示")
else:
self.IP_Addr1.SetValue("")
self.UserName1.SetValue("")
self.password1.SetValue("")
self.up_monitor.SetLabel("") def ServerMonitor(self):
#@author: 9527 Load_list1 = self.Info_List2 #实例化Remote_management_WayKind类
self.Ssh_load = MESRM.Remote_management_WayKind() if self.action_or_stop == True: for Load_list in Load_list1: td = Thread(target=self.Use_Monitor, args=(self, Load_list))
td.setDaemon(1)
td.start() else:
self.log_info1.AppendText('连接失败请重试\n')
pass def Use_Monitor(self, parent, Load_list):
#@author: 9527 #调用MESRM.Remote_management_WayKind的Command_Way方法
#传参parent为self是启用进程的MainFrameUI本身,Load_List为登陆了认证信息
print("调用进程已启用: ", Load_list)
self.Ssh_load.Command_Way(parent,Load_list) def ChangeLoopParameter(self,event):
#@author: 9527 event.Skip()
td = Thread(target=self.LoopControl)
td.setDaemon(1)
td.start() def LoopControl(self):
#@author: 9527 if self.action_or_stop == True:
self.action_or_stop=False
else :
self.action_or_stop=True def LogInfodisplay(self):
#@author: 9527 while True : AnswerInfo = self.QueueInfo.get() #调用UI的文本控件log_info1添加文本AppendText()
self.log_info1.AppendText(AnswerInfo) #计算文本控件行数
Text_counter = self.log_info1.GetNumberOfLines() #判断行数长度,移除前1000字符串
if Text_counter > 200: self.log_info1.Remove(0,1000)

3)SSH登录执行部分MultipleEffectiveServerResourceMonitorUI

#-*- coding: utf-8 -*-
#!/usr/bin/python
#@author: 9527 '''
用法: sar [ 选项 ] [ <时间间隔> [ <次数> ] ] 主选项和报告:
-b I/O 和传输速率信息状况
-B 分页状况
-d 块设备状况
-I { <中断> | SUM | ALL | XALL } 中断信息状况
-m 电源管理信息状况
-n { <关键词> [,...] | ALL } 网络统计信息
关键词可以是:
DEV 网卡信息统计
EDEV 网卡的错误统计
NFS NFS客户端
NFSD NFS服务器
SOCK Sockets (IPV4套接字)
IP IP流(IPV4)
EIP IP流的错误统计(IPV4)
ICMP ICMP流(IPV4)
EICMP ICMP流的错误统计(IPV4)
TCP TCP流(IPV4)
ETCP TCP流的错误统计(IPV4)
UDP UDP流(IPV4)
SOCK6 Sockets(IPV6套接字)
IP6 IP流(IPV6)
EIP6 IP流的错误统计(IPV6)
ICMP6 ICMP流(IPV6)
EICMP6 ICMP流的错误统计 (IPV6)
UDP6 UDP流(IPV6)
-q 队列长度和平均负载
-r 内存利用率
-R 内存状况
-S 交换空间利用率
-u [ ALL ]
CPU 利用率
-v Kernel table 状况
-w 任务创建与系统转换统计信息
-W 交换信息
-y TTY 设备状况
-o {<文件路径>}
将命令结果以二进制格式存放在指定文件中 ''' import paramiko class Remote_management_WayKind():
#@author: 9527 def __init__(self): self def Command_Way(self, parent,Load_list):
#@author: 9527 host_addr = Load_list[0]
user_name = Load_list[1]
ssh_loadkey = Load_list[2]
execmd01 = Load_list[3] #创建SSH连接日志文件
paramiko.util.log_to_file("paramiko666.log")
# 创建SSH对象
ssh_load = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh_load.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器
ssh_load.connect(hostname=host_addr, port=22, username=user_name, password=ssh_loadkey) # 执行命令
stdin, stdout, stderr = ssh_load.exec_command (execmd01, bufsize=1) #execmd传的参数free也是命令 stderr.channel.set_combine_stderr(stdout) #打开屏幕打印log文件,如果没有便新创建,模式a+为追加模式
log_file = open(host_addr+".log", "a+") while parent.action_or_stop: #读取正常返回信息
back_normal_info = stdout.readline() if len(back_normal_info) == 0:
break back_normal_info = host_addr + str("设备信息----- \n") +back_normal_info print(back_normal_info) #向队列压入数据,队列在MainFrame中定义
parent.QueueInfo.put(back_normal_info) #写入信息
log_file.writelines(back_normal_info) if parent.action_or_stop == 0: #调用UI的文本控件log_info1添加文本AppendText()
parent.QueueInfo.put("********************"+ host_addr + "**********已暂停监控**************\n") #关闭屏幕打印log文件
log_file.close() # 关闭连接
ssh_load.close()

4)图标定义部分PicturepackageUI

#coding:utf8
from wx.lib.embeddedimage import PyEmbeddedImage monitor_png = PyEmbeddedImage("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") find_png = PyEmbeddedImage("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") Lock_png = PyEmbeddedImage("iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADSUlEQVRIS7WWP4zcRBSHf288Y693vbfH5cIhRAKIKETJNSESokU0ICQEBVAgpQEakFIhSkQNHU2a1EFCSgIVCBBCgeZoDqQgQQDlhDZEl4S77F/bY48fxS4be2xv9iD5Oj979vN789ZviJlxL5EAmFnrOMvupklKqZTCRGBMqrW2H/l/GJPeFhSLxAADImMIysenMOwFeYjsNdK6FtfPU9Tdvv+tL26op1awvs8nojAcT+6mJrt6Y2CyrLhoChHWVoKmp/JBW0DJDiV/xyYdGTVKIYQgIiKa9EKWcWpMVpsBGWO7iZmTJImicBowIViz7PQTBBJSEIB8pyVpltVmQEo5kxoRURC0Uc4Ajg/4BHQUUPzpCUoKQFjBOdgCIlHapz3AzNY72QLf9x3HsYKLE8eR1fG24K6zqCBJ0+5f29du7nhKHnzwgdWV5XLLV7KQ4Odf/zj98YXLW91YayFEu9V8+snjb7z6Qjto2Y+WsNu02WxZe7Cxeem9j86EsQYgiPjf1lo/9MgH774dFB2zPahv0yI7u70Pz5wNY70ctE6++OyJ9SOD0ejTry5+s7F56fet02cvvPPma/NrdQfBl99tXN+91fDc90+9/sT6kUnw2OFDneCTc19f/PaHzZMvPbe2f19xUYE7CH785TcAJ44ePn7s8VnQccQrzz/z+fcbw3F4pXvtvwuYeRxGAA6s7bfq0A5avuuOo7jX6+fjZeYJFsH+kpSYJxgmLBvNVnspk95uXPjAjTU3WkGLSUPqjN3K0QFgTptuDdLP/gyHYZQZI5VSys0vY3Achszsut5DS+7LjzYnjj206eV+OkqZlOcoMKBLE1t4PgADXB2ZvubVRnUStYL6qVIB1+9FraDMINLd3tCTzsP3LTn1RbfYg+DmKNQm0yYbat1pePbtGmzBbByWZ5nvqn6cCCKvNDCMyYwBqgprC2btlKbFG0Cn4W4Pxp50PFVYxUAchePqOV0SzCHNmIDKM4v92jkkgLlfw9v4ynlstUPAYo9PkQCkVJ5nD2tHpIDJR6QQ0q04TxDgKtd1C97ZUJmWyHULf1QAB9rip1vhnNxntJRYbnqerE5semQrw4wrg7SXVFQ8DwEHA7niVWQ24R9+NXciwcXtRQAAAABJRU5ErkJggg==")

UI界面实现SSH登录服务器并执行命令监控的更多相关文章

  1. Python通过ssh连接服务器并执行命令

    [本文出自天外归云的博客园] 脚本示例如下: # coding:utf-8 import time,paramiko,re,StringIO def exec_shell(command): ''' ...

  2. expect远程登录服务器并执行命令

    #!/usr/bin/expectset timeout 120            #设置执行超时时间,任何输入120秒后退出set password "password"  ...

  3. ssh远程连接linux服务器并执行命令

    详细方法: SSHClient中的方法 参数和参数说明 connect(实现ssh连接和校验) hostname:目标主机地址 port:主机端口 username:校验的用户名 password:登 ...

  4. java ssh远程服务器并执行多条shell命令

    java ssh远程服务器并执行多条命令 import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...

  5. ssh登录服务器提示错误no hostkey alg

    ssh登录服务器提示错误no hostkey alg ssh root@192.168.1.100 -vvv 提示失败: no hostkey alg 登录到192.168.1.100服务器 rm - ...

  6. centos linux ip地址无法连接数据库,ssh登录服务器时必须使用22端口

    问题一:连接数据库时直接使用ip地址无法连接,必须使用ssh方式才能连接? 问题二:ssh登录服务器时必须使用22端口,在/etc/ssh/sshd_config中添加了10086端口,防火墙中已开启 ...

  7. Mac 无密码 SSH 登录服务器

    Mac 无密码 SSH 登录服务器,只需要简单三步,不再需要记住账号密码,快速进入服务器 第一步,生成密钥对 在当前用户下创建.ssh目录 mkdir ~/.ssh 使用命令ssh-keygen生成密 ...

  8. 【Shell实战】批量在多台服务器上执行命令

    功能说明:批量在多台服务器上执行命令 #!/bin/bash # ========================================== # 功能:批量在多台服务器上执行命令 # 方法: ...

  9. Python 实现远程服务器批量执行命令

    paramiko 远程控制介绍 Python paramiko是一个相当好用的远程登录模块,采用ssh协议,可以实现linux服务器的ssh远程登录.首先来看一个简单的例子 import parami ...

  10. python paramiko实现ssh上传下载执行命令

    paramiko ssh上传下载执行命令 序言 最近项目经常需要动态在跳板机上登录服务器进行部署环境,且服务器比较多,每次完成所有服务器到环境部署执行耗费大量时间.为了解决这个问题,根据所学的执行实现 ...

随机推荐

  1. Android studio学习第二期

    layout目录下app页面布局文件 activity_main.xml的创建和跳转 activity为一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务 创建步骤 这里选择第二个xml ...

  2. git reset 加不加 --hard的区别

    通常我们提交代码一般都是 git add ,git commit -m,   git push的这么个流程.添加到暂存区,提交到git库生成版本号,push到远程仓库以供他人可以使用.这是一个完整的且 ...

  3. js 比较两个数组对象,取不同的值

    let array1 = [ {'Num': 'A ', 'Name': 't1 '}, {'Num': 'B', 'Name': 't2'}, {'Num': 'C ', 'Name': 't3 ' ...

  4. Windows MFC HTTP POST请求 函数流程

    Windows MFC HTTP POST请求 函数流程 1 CString m_strHttpUrl(_T("http://10.200.80.86:8090/course/upload& ...

  5. vue+antd实现PDF预览(后端返回的是文件流)

    操作步骤: 第一步:下载包   npm install --save vue-pdf 第二步:导入组件 第三步:使用pdf标签进行展示,showUrl指的是访问路径 第四步:定义要用到的变量 第五步: ...

  6. openEuler22.09初始化脚本

    #!/bin/bash s=`nmcli d | grep "已断开" | awk '{print $1}'` echo /etc/sysconfig/network-script ...

  7. 【编程】Python3 使用自定义编码字符表解密Base64数据

    前言 Python提供了"base64"模块用于编码.解码Base64数据.但是并不是所有的Base64数据都会使用默认的字符表进行编码,所以这里对Python下实现自定义编码字符 ...

  8. java初学者-手动输入一个整数,打印这个数是几位数

    import.java.until.Scanner; //手动输入一个整数,打印这个数是几位数 public static void main(String[]args){ //键盘录入 Scanne ...

  9. 解决 vue init webpack 报错问题 报错原因是因为不能执行脚本文件。

    解决方案: 运行下面一行代码: set-ExecutionPolicy RemoteSigned 

  10. 浙里办微信小程序总结

    浙里办微信小程序单点登录流程 1.获取浙里办跳转地址中ticket或者微信小程序中的ticketId let ticket = getQueryString("ticket", w ...