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不带重复的全排列代码
Aug 13 Python
Python实现的概率分布运算操作示例
Aug 14 Python
Python 12306抢火车票脚本 Python京东抢手机脚本
Feb 06 Python
浅析PHP与Python进行数据交互
May 15 Python
Python3实现转换Image图片格式
Jun 21 Python
浅谈python中拼接路径os.path.join斜杠的问题
Oct 23 Python
对Python信号处理模块signal详解
Jan 09 Python
Python进程,多进程,获取进程id,给子进程传递参数操作示例
Oct 11 Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
Jan 25 Python
python数据类型可变不可变知识点总结
Mar 06 Python
安装多个版本的TensorFlow的方法步骤
Apr 21 Python
Python爬虫之爬取哔哩哔哩热门视频排行榜
Apr 28 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
制作特殊字的脚本
2006/06/26 Javascript
js 数组克隆方法 小结
2010/03/20 Javascript
JQuery操作单选按钮以及复选按钮示例
2013/09/23 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
理解javascript异步编程
2016/01/27 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
使用jquery datatable和bootsrap创建表格实例代码
2017/03/17 Javascript
详解Vue单元测试Karma+Mocha学习笔记
2018/01/31 Javascript
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
2019/02/01 Javascript
Angular使用ControlValueAccessor创建自定义表单控件
2019/03/08 Javascript
Vue中computed和watch有哪些区别
2020/12/19 Vue.js
python 中文乱码问题深入分析
2011/03/13 Python
Python的爬虫包Beautiful Soup中用正则表达式来搜索
2016/01/20 Python
Python之pymysql的使用小结
2019/07/01 Python
pandas取出重复数据的方法
2019/07/04 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
python读文件的步骤
2019/10/08 Python
python命令 -u参数用法解析
2019/10/24 Python
基于Python获取城市近7天天气预报
2019/11/26 Python
ansible动态Inventory主机清单配置遇到的坑
2020/01/19 Python
容易被忽略的Python内置类型
2020/09/03 Python
python实现图像随机裁剪的示例代码
2020/12/10 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
公司JAVA开发面试题
2015/04/02 面试题
建筑自我鉴定
2013/10/19 职场文书
自我评价中英文语句
2013/11/30 职场文书
办公设备采购方案
2014/03/16 职场文书
大学生全国两会报告感想
2014/03/17 职场文书
《北京的春节》教学反思
2014/04/07 职场文书
遗嘱范文
2015/08/07 职场文书
Python使用scapy模块发包收包
2021/05/07 Python
vue项目打包后路由错误的解决方法
2022/04/13 Vue.js