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实现给qq邮箱发送邮件的方法
May 28 Python
Python实现新浪博客备份的方法
Apr 27 Python
通过Python爬虫代理IP快速增加博客阅读量
Dec 14 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
Jul 11 Python
pycharm下打开、执行并调试scrapy爬虫程序的方法
Nov 29 Python
python字符串和常用数据结构知识总结
May 21 Python
Python实现微信翻译机器人的方法
Aug 13 Python
对Pytorch中Tensor的各种池化操作解析
Jan 03 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
Feb 27 Python
python3代码中实现加法重载的实例
Dec 03 Python
Python爬取用户观影数据并分析用户与电影之间的隐藏信息!
Jun 29 Python
PyCharm 配置SSH和SFTP连接远程服务器
May 11 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简单解析mysqli查询结果的方法(2种方法)
2016/06/29 PHP
PHP加密解密类实例代码
2016/07/20 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
用javascript实现给出的盒子的序列是否可连为一矩型
2007/08/30 Javascript
createElement动态创建HTML对象脚本代码
2008/11/24 Javascript
jquery实现metro效果示例代码
2013/09/06 Javascript
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
jQuery实现对网页节点的增删改查功能示例
2017/09/18 jQuery
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
Node.js readline模块与util模块的使用
2018/03/01 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
vue项目在安卓低版本机显示空白的原因分析(两种)
2018/09/04 Javascript
[01:08:48]LGD vs OG 2018国际邀请赛淘汰赛BO3 第三场 8.25
2018/08/29 DOTA
[54:53]完美世界DOTA2联赛PWL S2 GXR vs PXG 第二场 11.18
2020/11/18 DOTA
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
Python自定义进程池实例分析【生产者、消费者模型问题】
2016/09/19 Python
Python装饰器的执行过程实例分析
2018/06/04 Python
python库matplotlib绘制坐标图
2019/10/18 Python
Python开发企业微信机器人每天定时发消息实例
2020/03/17 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
2020/07/30 Python
HTML5 Convas APIs方法详解
2015/04/24 HTML / CSS
HTML5新增属性data-*和js/jquery之间的交互及注意事项
2017/08/08 HTML / CSS
你所在的项目是如何确定版本号的
2015/12/28 面试题
家电业务员岗位职责
2014/03/10 职场文书
给全校老师的建议书
2014/03/13 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
不听老师话的万能检讨书
2014/10/04 职场文书
英文感谢信范文
2015/01/21 职场文书
顶岗实习协议书
2015/01/29 职场文书
黄石寨导游词
2015/02/05 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
Django实现翻页的示例代码
2021/05/24 Python