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 获取文件列表(或是目录例表)
Mar 25 Python
Python中优化NumPy包使用性能的教程
Apr 23 Python
在Python中使用第三方模块的教程
Apr 27 Python
用python生成1000个txt文件的方法
Oct 25 Python
Python设计模式之模板方法模式实例详解
Jan 17 Python
python+opencv实现摄像头调用的方法
Jun 22 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
Jun 08 Python
通过实例解析python创建进程常用方法
Jun 19 Python
Python 解析xml文件的示例
Sep 29 Python
TensorFlow低版本代码自动升级为1.0版本
Feb 20 Python
python Protobuf定义消息类型知识点讲解
Mar 02 Python
python 通过使用Yolact训练数据集
Apr 06 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/10/09 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
给ECShop添加最新评论
2015/01/07 PHP
在php和MySql中计算时间差的方法详解
2015/03/27 PHP
PHP+MySQL实现在线测试答题实例
2020/01/02 PHP
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
JS实现距离上次刷新已过多少秒示例
2014/05/23 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
jquery点击缩略图切换视频播放特效代码分享
2015/09/15 Javascript
jQuery中ScrollTo用法示例
2016/09/04 Javascript
JS简单实现滑动加载数据的方法示例
2017/10/18 Javascript
浅谈React深度编程之受控组件与非受控组件
2017/12/26 Javascript
如何安装控制器JavaScript生成插件详解
2018/10/21 Javascript
Js通过AES加密后PHP用Openssl解密的方法
2019/07/12 Javascript
vue-以文件流-blob-的形式-下载-导出文件操作
2020/08/07 Javascript
[02:32]DOTA2亚洲邀请赛 VG战队巡礼
2015/02/03 DOTA
Python urlopen 使用小示例
2008/09/06 Python
Python3基础之输入和输出实例分析
2014/08/18 Python
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
Python机器学习之决策树算法实例详解
2017/12/06 Python
Python使用循环神经网络解决文本分类问题的方法详解
2020/01/16 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
python实现密码强度校验
2020/03/18 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
2020/04/24 Python
俄罗斯最大的在线手表商店:Bestwatch.ru
2020/01/11 全球购物
请解释接口的显式实现有什么意义
2012/05/26 面试题
自动化工程专业个人应聘自荐信
2013/09/26 职场文书
外贸实习生自荐信范文
2013/11/24 职场文书
历史专业个人求职信分享
2013/12/20 职场文书
装修致歉信
2014/01/15 职场文书
公司经理聘任书
2014/03/29 职场文书
出租房屋协议书
2014/09/14 职场文书
镇政府副镇长群众路线专题民主生活会对照检查材料
2014/09/19 职场文书
谢师宴学生致辞
2015/07/27 职场文书
优秀学生干部主要事迹材料
2015/11/04 职场文书