1. 程式人生 > >使用Python實時獲取cmd的輸出

使用Python實時獲取cmd的輸出

轉自 :https://www.cnblogs.com/podolski/p/5040107.html

最近發現一個問題,一個小夥兒寫的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埠的地址行,有就說明活著,否則就是掛了。