Python实时获取cmd的输出

最近发现一个问题,一个小伙儿写的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的输出的相关知识,希望大家喜欢。

(0)

相关推荐

  • python应用程序在windows下不出现cmd窗口的办法

    python写的GTK程序,会有这样一个怪现象,本来在cmd下用 python xxx.py 启动,还好好的,但是用py2exe编译以后,再用subprocess调用命令行程序的时候,就发现一个黑乎乎的cmd窗口跳出来了,特别难看,要消除它其实也还比较容易,但是要使用startupinfo这个windows only的参数,以下代码是linux和windows通用的例子: 复制代码 代码如下: if os.name == 'nt':    startupinfo = subprocess.STA

  • python调用cmd复制文件代码分享

    复制代码 代码如下: import os def load() :    filename = os.getcwd() + r'\fromto.txt'    if os.path.isfile(filename) :                f = open(filename)        try :            lines = f.readlines()        finally :            f.close()            return line

  • python调用cmd命令行制作刷博器

    复制代码 代码如下: import webbrowser as webimport timeimport os count=0while count<10:    count=count+1    #你要刷的博客    web.open_new_tab("这里是博客地址")    time.sleep(1)else:    os.system('taskkill /F /IM  360se.exe') 这里主要学到三个知识点: 1.Python的线程原来是在time模块下 2.P

  • linux系统使用python监测网络接口获取网络的输入输出

    net.py 获取网络接口的输入和输出 复制代码 代码如下: #!/usr/bin/env Pythonimport timeimport sys if len(sys.argv) > 1: INTERFACE = sys.argv[1]else: INTERFACE = 'eth0'STATS = []print 'Interface:',INTERFACE def rx(): ifstat = open('/proc/net/dev').readlines() for interface i

  • Python使用CMD模块更优雅的运行脚本

    本文实例讲述了Python使用CMD模块更优雅的运行脚本的方法.分享给大家供大家参考.具体分析如下: 平时由于经常给测试人员调试一些东西,虽然写了一些脚本,感觉还是不方便. python的cmd模块提供的更优雅的方式,很喜欢. 刚写了一些平时常用的测试代码: # -*- coding:utf-8 -*- import os, sys from datetime import datetime import cmd import warnings from django.conf import s

  • Python实时获取cmd的输出

    最近发现一个问题,一个小伙儿写的console程序不够健壮,监听SOCKET的时候容易崩,造成程序的整体奔溃,无奈他没有找到问题的解决办法,一直解决不了,可是这又是一个监控程序,还是比较要紧的,又必须想办法解决. (这是要搞死我的节奏啊....)由于个人不太懂他用的语言,只能在程序外围想办法. 环境描述: 1. 目标程序执行时会监听8080端口,TCP,并在每一次client连接后通过console输出client的IP地址. 2. 监听不是一次性完成的,而是一直监听,程序并不会退出 3. 为了

  • python实时获取外部程序输出结果的方法

    如下所示: s=subprocess.Popen("ping baidu.com -t",bufsize=0,stdout=subprocess.PIPE,universal_newlines=True) while True: nextline=s.stdout.readline() print(nextline.strip()) if nextline=="" and scan.poll()!=None: break 以上这篇python实时获取外部程序输出结果

  • Python 实时获取任务请求对应的Nginx日志的方法

    需求描述 项目需求测试过程中,需要向Nginx服务器发送一些用例请求,然后查看对应的Nginx日志,判断是否存在特征内容,来判断任务是否执行成功.为了提升效率,需要将这一过程实现自动化. 实践环境 Python 3.6.5 代码设计与实现 #!/usr/bin/env python # -*- coding:utf-8 -*- ''' @CreateTime: 2021/06/26 9:05 @Author : shouke ''' import time import threading im

  • 利用Python实时获取steam特惠游戏数据

    目录 前言 代码部分 开发环境 先导入本次所需的模块 请求数据 获取请求的数据 解析数据 保存数据 前言 Steam是由美国电子游戏商Valve于2003年9月12日推出的数字发行平台,被认为是计算机游戏界最大的数码发行平台之一,Steam平台是全球最大的综合性数字发行平台之一.玩家可以在该平台购买.下载.讨论.上传和分享游戏和软件. 而每周的steam会开启了一轮特惠,可以让游戏打折,而玩家就会购买心仪的游戏 传说每次有大折扣,无数的玩家会去购买游戏,可以让G胖亏死 不过,由于种种原因,我总会

  • paramiko使用tail实时获取服务器的日志输出详解

    基本思路 现在有这么一个需求需要实现自动化:需要实时获取服务器cpu,gpu温度以及传感器信息上报情况,对高低温环境下对于设备运行状态的影响进行测试.基本思路为利用paramiko ssh到服务器上,起一个线程用tail -f命令实时获取日志输出,起另外一个线程用'cat /sys/class/thermal/thermal_zone0/temp'命令定时获取cpu,gpu温度. 代码 def get_report_info_perid(self, cmd, diff_time, thre_ti

  • Python 从subprocess运行的子进程中实时获取输出的例子

    有些时候,我们需要将某些程序放到子进程中去运行,以达到整合系统的目的.在Python中,一个非常好的选择就是使用subprocess模块,本模块为开辟子进程去执行子程序提供了统一的接口,更加便于学习和使用. 同时,对于在子进程里的程序,我们希望能够实时获取其输出,以在主进程中打印相关信息,使我们能够了解当前子程序的执行进度.对此,subprocess模块也提供了相应的参数,能够将子程序的标准输出和标准错误输出返回给主程序. 下面,我们就通过一个例子来说明这个功能.首先,我们需要一个用于模拟标准输

  • python如何实时获取tcpdump输出

    一.背景 今天有个小需求,要确认客户端有没有往服务端发送udp包,但为了减轻工作量,不想每次到机器上手动执行tcpdump抓包命令. 于是就写了个脚本来释放人力. 二.代码实现 整个脚本我还加了一些其他功能:时间戳.发送端IP提取,数据包分析,数据持久化等.这里都先去掉,仅记录下简单的实时获取tcpdump输出功能. 代码如下: # -*- coding: utf-8 -*- # !/usr/bin/env python # sudo tcpdump -tt -l -nn -c 5 -i enp

  • 实时获取Python的print输出流方法

    我的应用场景是:使用shell执行python文件,并且通过调用的返回值获取python的标准输出流. shell程序如下: cmd='python '$1' '$2' '$3' '$5' '$4 RESULT=eval $cmd echo $RESULT 之前我的写的python程序如下: # coding: utf-8 import time import json def execute(_database, _parameter): print 'sleep start' sleepTi

  • python Popen 获取输出,等待运行完成示例

    我就废话不多说了,直接上代码吧! import subprocess def excuteCommand(com): ex = subprocess.Popen(com, stdout=subprocess.PIPE, shell=True) out, err = ex.communicate() status = ex.wait() print("cmd in:", com) print("cmd out: ", out.decode()) return out.

  • python 调用pyautogui 实时获取鼠标的位置、移动鼠标的方法

    PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以用程序自动控制鼠标和键盘操作,利用它可以实现自动化任务 本章介绍了许多不同函数,下面是快速的汇总参考: moveTo(x,y)将鼠标移动到指定的 x.y 坐标. moveRel (xOffset,yOffset)相对于当前位置移动鼠标. dragTo(x,y)按下左键移动鼠标. dragRel (xOffset,yOffset)按下左键,相对于当前位置移动鼠标. click(x,y,button)模拟点击(默认是左键). ri

随机推荐