2012-12-17 2 views
2

나는 서브 프로세스 실행이 :파이썬은 json을 리턴하는 서브 프로세스를 반복 하는가?

lshw -json -C network 

난 뒤 다음을받을 경우

{ 
    "id" : "network", 
    "class" : "network", 
    "claimed" : true, 
    "handle" : "PCI:0000:00:05.0", 
    "description" : "Ethernet interface", 
    "product" : "82545EM Gigabit Ethernet Controller (Copper)", 
    "vendor" : "Intel Corporation", 
    "physid" : "5", 
    "businfo" : "[email protected]:00:05.0", 
    "logicalname" : "eth0", 
    "version" : "00", 
    "serial" : "00:8c:42:77:58:49", 
    "units" : "bit/s", 
    "size" : 1000000000, 
    "capacity" : 1000000000, 
    "width" : 32, 
    "clock" : 66000000, 
    "configuration" : { 
     "autonegotiation" : "on", 
     "broadcast" : "yes", 
     "driver" : "e1000", 
     "driverversion" : "7.3.21-k8-NAPI", 
     "duplex" : "full", 
     "firmware" : "N/A", 
     "ip" : "10.211.55.10", 
     "latency" : "0", 
     "link" : "yes", 
     "multicast" : "yes", 
     "port" : "twisted pair", 
     "speed" : "1Gbit/s" 
    }, 
    "capabilities" : { 
     "msi" : "Message Signalled Interrupts", 
     "bus_master" : "bus mastering", 
     "cap_list" : "PCI capabilities listing", 
     "ethernet" : true, 
     "physical" : "Physical interface", 
     "logical" : "Logical interface", 
     "tp" : "twisted pair", 
     "10bt" : "10Mbit/s", 
     "10bt-fd" : "10Mbit/s (full duplex)", 
     "100bt" : "100Mbit/s", 
     "100bt-fd" : "100Mbit/s (full duplex)", 
     "1000bt-fd" : "1Gbit/s (full duplex)", 
     "autonegotiation" : "Auto-negotiation" 
    } 
    }, 

내가 아마도 내가보다가 있다는 경우 (모든 네트워크 인터페이스를 캡처하기 위해이 반복 수 하나는) 내 시스템의 경우가 아닙니다. 또한,이 출력에서 ​​1 또는 2를 어떻게 선택할 수 있습니까? 전체 데이터가 필요하지 않습니다. 당신이 -json 출력 -C 수준의 필터링을 결합 할 수 없습니다 불행히도

def get_nic_data(): 
     lshw_cmd = "lshw -json -C network" 
     proc = subprocess.Popen(lshw_cmd, shell=True, stdout=subprocess.PIPE, 
                 stdin=subprocess.PIPE) 
     return proc.stdout 


def read_data(proc_output): 
     import simplejason as json 
     json_obj = json 

     json_obj.loads(proc_output) 

     #Obtain Vendor,Description,Product 
     #... 
     #... 

     json_obj.dumps(obtained_data_here) 

     #Not sure if this would work this way. 


    read_data(get_nic_data()) 

답변

6

;

나는 다음 사항을 염두에 있었다 최신 버전에서도 JSON 출력이 심각하게 손상되었습니다. 대신 전체 JSON 출력을 필터링하십시오. subprocess을 사용할 때는 shell=True을 사용하지 말고 대신 목록을 전달하십시오. stdin을 파이프 할 필요가 없지만 stderr를 포착 (침묵)하십시오.

그리고 우리는 일치 'class' 키가 무엇을 따기는 '어린이'구조를 통해 재귀 수 있습니다

def get_nic_data(): 
    lshw_cmd = ['lshw', '-json'] 
    proc = subprocess.Popen(lshw_cmd, stdout=subprocess.PIPE, 
             stderr=subprocess.PIPE) 
    return proc.communicate()[0] 

def find_class(data, class_): 
    for entry in data.get('children', []): 
     if entry.get('class') == class_: 
      yield entry 

     for child in find_class(entry, class_): 
      yield child 

def read_data(proc_output, class_='network'): 
    import json 

    for entry in find_class(json.loads(proc_output), class_): 
     yield entry['vendor'], entry['description'], entry['product'] 

다음 루프 read_data(get_nic_data()) 이상 :

for vendor, description, product in read_data(get_nic_data()): 
    print vendor, description, product 
+0

'lshw -json'은 (적어도 내 컴퓨터에서는) 유효한 json 텍스트를 반환하지 않습니다. – jfs

+0

'lshw -json'은 같은 클래스에 대해 여러 개의 결과가있을 경우 유효한 JSON을 반환하지 않습니다. 배열로 있어야하지만'['및']'가 누락 된 것 같습니다. – Raber

+0

@JFSebastian : Bugger, 나는 그랬 으면 좋겠다. OP 부분에서의 실수. 나는 최근에'lshw' 릴리즈 (편리한 데비안 스퀴즈가 내 서버에 있습니다)를 가지고 있지 않았습니다. 누락 된 것,'['및']'대괄호? –

0

여러 네트워크 카드가있는 경우 lshw은 유효한 json 텍스트를 반환하지 않습니다.

import json 
import re 
from subprocess import STDOUT, check_output as qx 

# get command output 
output = qx("lshw -json -C network".split(), stderr=STDOUT) 

# get json parts 
_, sep, json_parts = output.rpartition(b"\r") 
if not sep: # no \r in the output 
    json_parts = output 

# convert it to valid json list 
jbytes = b"[" + re.sub(b"}(*){", b"}, {", json_parts) + b"]" 
L = json.loads(jbytes.decode()) 

# pretty print 
import sys 
json.dump(L, sys.stdout, indent=4) 

청소기 용액 쉽게 감아 잘 형성된 XML로 변환 될 수있는 출력을 생성 lshw -xml를 사용할 것이다 : 그것은 출력 직전/직후 [/] 추가 물체 사이 ,을 추가로 개선 될 수있다 루트 요소 : '<root>' + 출력 + '</root>'.

+0

오류가 발생했습니다. ValueError : No JSON 객체가 디코딩 될 수 있습니다. – Dayan

+0

@Dayan : 테스트 해봤는데 내 컴퓨터에서 작동합니다. 해결책은 lshw 출력의 변화에 ​​대해 취약하기 때문에 @Martijn이 유효한 json을 얻으려면 제안 된대로'-C' 옵션을 삭제하십시오. – jfs

관련 문제