0

I essentially want to get some values from a command like 'ipconfig', but when I print the output of the command I get alot of newline characters and spaces.

Code I've Tried:

>>> import subprocess
>>> output = subprocess.getstatusoutput("ipconfig")
>>> print(output)
(0, '\x0c\nWindows IP Configuration\n\n\nEthernet adapter Ethernet 2:\n\n   Media State . . . . . . . . . . . : Media disconnected\n   Connection-specific DNS Suffix  . : \n\nEthernet adapter Npcap Loopback Adapter:\n\n  
 Connection-specific DNS Suffix  . : \n   Link-local IPv6 Address . . . . . : ~e~~::7dab:~~7f:e56f:1131%9\n   Autoconfiguration IPv4 Address. . : 169.~~4.1~.49\n   
Subnet Mask . . . . . . . . . . . : 255.255.0.0\n   Default Gateway . . . . . . . . . : \n\nEthernet adapter VirtualBox Host-Only Network:\n\n   Connection-specific DNS Suffix  . : \n 
Link-local IPv6 Address . . . . . : fe80::7~~c:69aa:~~aa:~~14~10\n   IPv4 Address. . . . . . . . . . . : 192.168.~~.~\n   Subnet Mask . . . . . . . . . . . : 255.~~~.255.0\n   Default Gateway  . . . . : etc...

I'm not sure of the best way to parse this data into some sort of table with keys and values

And when trying to use code from this answer to this question here, all I could get was this error:

>>> import subprocess
>>> output = subprocess.check_output("ipconfig", shell=True)
>>> result = {}
>>> for row in output.split('\n'):
...     if ': ' in row:
...         key, value = row.split(': ')
...         result[key.strip(' .')] = value.strip()
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
>>> print(result)
{}
>>> print(result['A (Host) Record'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'A (Host) Record'

Example of what I'm looking for:

"Link-local IPv6 Address" : "my ipv6 addr"

"Subnet Mask" : "my subnet mask"

(Using python 3)

4
  • 1
    What specific info are you trying to get? There might be an API to get it, which would totally circumvent this problem. Commented Oct 6, 2019 at 20:02
  • 1
    Another option is wmic, which can output XML: stackoverflow.com/a/41638971/4518341 Commented Oct 6, 2019 at 20:07
  • @wjandrea I don't want any particular info, otherwise i would be using a module. I just want to parse the data into a dictionary type structure. I will try to use the wmic option Commented Oct 6, 2019 at 21:08
  • 1
    So your end goal is to learn how to parse the output? Commented Oct 6, 2019 at 21:10

1 Answer 1

1

We get the output, decode it so it's a str, then iterate over its lines.

We'll store each separate adapter as a dict in a dict named adapters.

In the output, preceding the details of each adapter is a line starting with "Ethernet adapter ". We get the adapter's name by splicing the line from after the string "Ethernet adapter " to just before the ":" which is at index -1.

After that, it is assumed any line with " : " in it has details about the current adapter. So we split the line at " : ", clean it up a bit, and use them as key/value pairs for our current_adapter dict which we created earlier.

import subprocess

adapters = {}
output = subprocess.check_output("ipconfig").decode()

for line in output.splitlines():
    term = "Ethernet adapter "
    if line.startswith(term):
        adapter_name = line[len(term):-1]
        adapters[adapter_name] = {}
        current_adapter = adapters[adapter_name]
        continue

    split_at = " : "
    if split_at in line:
        key, value = line.split(split_at)
        key = key.replace(" .", "").strip()
        current_adapter[key] = value



for adapter_name, adapter in adapters.items():
    print(f"{adapter_name}:")
    for key, value in adapter.items():
        print(f"    '{key}' = '{value}'")
    print()

Output:

Ethernet:
    'Connection-specific DNS Suffix' = ''
    'Link-local IPv6 Address' = 'fe80::...'
    'IPv4 Address.' = '192.168.255.255'
    'Subnet Mask' = '255.255.255.255'
    'Default Gateway' = '192.168.255.255'

VMware Network Adapter VMnet1:
    'Connection-specific DNS Suffix' = ''
    'Link-local IPv6 Address' = 'fe80::...'
    'IPv4 Address.' = '192.168.255.255'
    'Subnet Mask' = '255.255.255.255'
    'Default Gateway' = ''

VMware Network Adapter VMnet8:
    'Connection-specific DNS Suffix' = ''
    'Link-local IPv6 Address' = 'fe80::...'
    'IPv4 Address.' = '192.168.255.255'
    'Subnet Mask' = '255.255.255.255'
    'Default Gateway' = ''
Sign up to request clarification or add additional context in comments.

2 Comments

It's worth noting this won't work if you've got wireless adapters or tunnel adapters, or if you use ipconfig /all. But it shouldn't take too long to modify it so it does.
@GordanAitchJay thanks a lot I modified your code a bit, and it works perfectly!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.