3

サブプロセスを実行しています:

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" : "pci@0000: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つを選択するにはどうすればよいですか?データ全体が必要です。

私は次のことを念頭に置いていました。

 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())
4

2 に答える 2

8

-C残念ながら、クラスフィルタリングと-json出力を組み合わせることはできません。最新バージョンでも、JSON出力はひどく壊れています。代わりに、完全なJSON出力を自分でフィルタリングします。shell=Trueを使用するときは使用を避けsubprocess、代わりにリストを渡す必要があることに注意してください。stdinをパイプする必要もありませんが、stderrをキャプチャ(無音)します。

次に、「children」構造を繰り返して、一致する'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
于 2012-12-17T09:51:31.900 に答える
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)

よりクリーンなソリューションを使用するlshw -xmlと、ルート要素でラップすることで整形式のxmlに簡単に変換できる出力が生成されます:'<root>'+output+ '</root>'

于 2012-12-17T10:18:55.363 に答える