Python实时获取cmd的输出


Posted in Python onDecember 13, 2015

最近发现一个问题,一个小伙儿写的console程序不够健壮,监听SOCKET的时候容易崩,造成程序的整体奔溃,无奈他没有找到问题的解决办法,一直解决不了,可是这又是一个监控程序,还是比较要紧的,又必须想办法解决。

(这是要搞死我的节奏啊....)由于个人不太懂他用的语言,只能在程序外围想办法。

环境描述:

1. 目标程序执行时会监听8080端口,TCP,并在每一次client连接后通过console输出client的IP地址。

2. 监听不是一次性完成的,而是一直监听,程序并不会退出

3. 为了监控需要,最好能对连接的IP进行排序,整理。

P.S. 系统基于windows平台。

想起来做监控程序,简单点比较好,于是想到了Python。

我的预想逻辑是这样的,通过python检测目标程序是否崩了,如果中标就启动目标程序,并进行监控,每输出一次,python进行一次数据运算整理,然后循环。

第一步,先搞定输出的捕获问题。

# this method is used for monitoring
import time
import subprocess
import locale
import codecs
mylist = []
ps = subprocess.Popen('netstat -a', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
while True:
  data = ps.stdout.readline()
  if data == b'':
    if ps.poll() is not None:
      break
  else:
    mylist.append(data.decode(codecs.lookup(locale.getpreferredencoding()).name))
    newlist = []
    for i in mylist:
      if i.find('192.168') > 0:
        newlist.append(i)
    newlist.sort()
    print('Sum of requests from LAN:', len(newlist))

我用netstat -a替代那个需要持续输出的程序,执行程序,发现程序和想象的不太一样,确实是实时获得数据了,但是感觉总是有点不太和谐,不管了,继续。

第二步,解决监控程序的问题

程序或者还是死的,有一点非常关键,就是监听端口,那只要检测一下端口就行了。三个办法:

1. 找端口检测的API

2. 连接一次目标端口,通了就是活的

3. netstat

第一种方法需要去找找有没有相关的API,第二种方法容易对目标程序的正常运行造成问题,第三种我想都没想就用了吧。这里需要用到cmd的重定向功能

# this method is used for monitoring
import time
import subprocess
import locale
import codecs
def getstdout(p):
  mylist = []
  while True:
    data = p.stdout.readline()
    if data == b'':
      if p.poll() is not None:
        break
    else:
      mylist.append(data.decode(codecs.lookup(locale.getpreferredencoding()).name))
  return mylist
while True:
  ps = subprocess.Popen('netstat -an | findstr "8080"', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
  resultlist = getstdout(ps)
  if len(resultlist) >= 1:
    pass
  else:
    print(time.strftime("%Y-%m-%d %H:%M:%S"))
    subprocess.Popen('taskkill.exe /f /im node.exe', shell=False)
 # 防止动作过快,把新建的程序整死了
    time.sleep(3)
    subprocess.Popen('start node D:\\app.js', shell=True)
  time.sleep(10)

netstat -an获得当前的端口监听情况,“|”将netstat的输出重定向到findstr函数

netstat -an | findstr "8080" 查找有8080端口的地址行,有就说明活着,否则就是挂了。

最后一步,整合

# this method is used for monitoring
import time
import subprocess
import locale
import codecs
def getstdout(p):
  mylist = []
  while True:
    data = p.stdout.readline()
    if data == b'':
      if p.poll() is not None:
        break
    else:
      mylist.append(data.decode(codecs.lookup(locale.getpreferredencoding()).name))
  return mylist
while True:
  ps = subprocess.Popen('netstat -an | findstr "8080"', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
  resultlist = getstdout(ps)
  if len(resultlist) >= 1:
    pass
  else:
    print(time.strftime("%Y-%m-%d %H:%M:%S"))
    subprocess.Popen('taskkill.exe /f /im node.exe', shell=False)
    time.sleep(3)
    pss = subprocess.Popen('start cmd.exe /k node app.js', stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, shell=True)
    alist = getstdout(pss)
    newlist = []
    for i in alist:
      if i.find('192.168') > 0:
        newlist.append(i)
    newlist.sort()
    print('Sum of requests from LAN:', len(newlist))
  time.sleep(10)

然后发现有问题,程序完全不会定时检测,只会卡在readline()上。

各种找问题,发现那个process.stdout.readline()是个同步方法,没结果就不返回。有没有的能异步的方法? 

有人用fnctl,windows不支持,pass

asyncio?看了半天没太明白...

折腾了半天,最后关头我还是用c#解决这个问题了....

参考代码见http://www.jiamaocode.com/Cts/1031.html,打不开的话http://www.cnblogs.com/sode/archive/2012/07/10/2583941.html有转载

总算解决了这个问题,但是我心中还是不爽,思考了很久如何解决异步readline()的问题。忽然想起来多线程这个利器,干脆开

一个线程,不返回就等着,不就问题解决了。

# this method is used for monitoring
import time
import subprocess
import locale
import codecs
import threading
alist = []
def getstdout(p, asy):
  if asy:
    alist.clear()
  mylist = []
  while True:
    data = p.stdout.readline()
    if data == b'':
      if p.poll() is not None:
        break
    else:
      if asy:
        alist.append(data.decode(codecs.lookup(locale.getpreferredencoding()).name))
      else:
        mylist.append(data.decode(codecs.lookup(locale.getpreferredencoding()).name))
  return mylist
while True:
  ps = subprocess.Popen('netstat -an | findstr ""', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
  resultlist = getstdout(ps, False)
  if len(resultlist) >= :
    newlist = []
    for i in alist:
      if i.find('.') > :
        newlist.append(i)
    newlist.sort()
    print('Sum of requests from LAN:', len(newlist))
  else:
    print(time.strftime("%Y-%m-%d %H:%M:%S"))
    subprocess.Popen('taskkill.exe /f /im node.exe', shell=False)
    time.sleep()
    pss = subprocess.Popen('start cmd.exe /k node app.js', stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, shell=True)
    th = threading.Thread(target=getstdout, args=[pss, True])
    th.start()
  time.sleep()

总结

有时候简单的解决方法也可以实现同样的功能,对比python的实现与C#的实现,C#更面向事件一点,python应该也有不错的解决方案,继续摸索...

以上内容是小编给大家分享的Python实时获取cmd的输出的相关知识,希望大家喜欢。

Python 相关文章推荐
Python导出DBF文件到Excel的方法
Jul 25 Python
python下os模块强大的重命名方法renames详解
Mar 07 Python
Python中正则表达式详解
May 17 Python
Python实现图片滑动式验证识别方法
Nov 09 Python
Flask-Mail用法实例分析
Jul 21 Python
使用python serial 获取所有的串口名称的实例
Jul 02 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
Nov 08 Python
Python异常继承关系和自定义异常实现代码实例
Feb 20 Python
Python Django中的STATIC_URL 设置和使用方式
Mar 27 Python
浅谈python量化 双均线策略(金叉死叉)
Jun 03 Python
教你怎么用Python操作MySql数据库
May 31 Python
Python matplotlib绘制雷达图
Apr 13 Python
一篇文章入门Python生态系统(Python新手入门指导)
Dec 11 #Python
深入源码解析Python中的对象与类型
Dec 11 #Python
Python实现各种排序算法的代码示例总结
Dec 11 #Python
Python操作MySQL数据库9个实用实例
Dec 11 #Python
使用Python编写简单的画图板程序的示例教程
Dec 08 #Python
一波神奇的Python语句、函数与方法的使用技巧总结
Dec 08 #Python
Python使用pygame模块编写俄罗斯方块游戏的代码实例
Dec 08 #Python
You might like
php运行提示:Fatal error Allowed memory size内存不足的解决方法
2014/12/17 PHP
PHP下载远程图片并保存到本地方法总结
2016/01/22 PHP
jQuery插件PageSlide实现左右侧栏导航菜单
2015/04/12 Javascript
jQuery构造函数init参数分析续
2015/05/13 Javascript
jQuery实现动画效果circle实例
2015/08/06 Javascript
JavaScript正则表达式的分组匹配详解
2016/02/13 Javascript
JavaScript中关于for循环删除数组元素内容时出现的问题
2016/11/21 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
2017/04/12 Javascript
js中的事件委托或是事件代理使用详解
2017/06/23 Javascript
基于匀速运动的实例讲解(侧边栏,淡入淡出)
2017/10/17 Javascript
element-ui上传一张图片后隐藏上传按钮功能
2019/05/22 Javascript
element form 校验数组每一项实例代码
2019/10/10 Javascript
详解vite2.0配置学习(typescript版本)
2021/02/25 Javascript
[02:07]DOTA2超级联赛专访BBC:难忘网吧超神经历
2013/06/09 DOTA
[05:08]DOTA2-DPC中国联赛3月6日Recap集锦
2021/03/11 DOTA
比较详细Python正则表达式操作指南(re使用)
2008/09/06 Python
Python3.0与2.X版本的区别实例分析
2014/08/25 Python
Python pyinotify日志监控系统处理日志的方法
2018/03/08 Python
Python3.6+Django2.0以上 xadmin站点的配置和使用教程图解
2019/06/04 Python
python文件操作的简单方法总结
2019/11/07 Python
python程序如何进行保存
2020/07/03 Python
html标签之Object和EMBED标签详解
2013/07/04 HTML / CSS
美国电视购物:QVC
2017/02/06 全球购物
美国女士泳装店:Swimsuits For All
2017/03/02 全球购物
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
马来西亚奢侈品牌购物商城:Valiram 247
2020/09/29 全球购物
SCHIESSER荷兰官方网站:德国内衣专家
2020/10/09 全球购物
人事科岗位职责范本
2014/03/02 职场文书
2014年元旦感言
2014/03/06 职场文书
2015年个人思想总结
2015/03/09 职场文书
2016大学生暑期三下乡心得体会
2016/01/23 职场文书
高效课堂教学反思
2016/02/24 职场文书
青年人初次创业的“五不要”
2019/08/23 职场文书
A22国内电台短波广播频率表
2022/05/10 无线电
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript