0

As a result of command ifconfig in Linux I just want to keep the int addr and Mask in two strings:

eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
          inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
          inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
          TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)

to get finally this:

inet_addr: "10.244.21.118"
mask="255.244.255.192"

Is there any faster way? My only idea is parsing every line and then searching for int addr and deleting the name... but I don't know if it works out.

4 Answers 4

3

3 general options in python:

  • Parse it out of a shell call to ifconfig. Your current approach, and the approach of all the other answers.
  • Use sockets. Set up a UDP socket to connect to an external host, look at its sockname and find its mask. You will have to deal with some (very) low-level APIs.
  • Use an external module. e.g. python-ifconfig.

Here's the basic form of the second approach using sockets:

import socket
import fcntl
import struct

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP

s.connect(('google.com',0)) #prepare UDP socket to connect to some external host

s.getsockname()
Out[17]: ('10.0.2.15', 56965)

socket.inet_ntoa(fcntl.ioctl(s, 0x891b, struct.pack('256s', 'eth0'))[20:24])
Out[18]: '255.255.255.0'

Credit to answerers in this thread for the mask solution, I did not know those opcodes off the top of my head :)

Sign up to request clarification or add additional context in comments.

Comments

1

Maybe like this?

#!/usr/local/cpython-3.3/bin/python

import re

def give_string():
    string = '''
eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
          inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
          inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
          TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)
    '''
    return string

def main():
    string = give_string()
    regex = re.compile('^.*inet addr:\s*(\d+\.\d+\.\d+\.\d+) .*Mask:\s*(\d+\.\d+\.\d+\.\d+).*$', re.MULTILINE | re.DOTALL)
    match = regex.match(string)
    ip_address = match.group(1)
    subnet_mask=match.group(2)
    print(ip_address, subnet_mask)

main()

BTW, I usually say that people overuse regex's, but this is a pretty good case for one.

Comments

1

Using Regular Expressions, you can accomplish this. The code below places everything in a devices list, but the for loop.

import re

ifconfig = """eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
          inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
          inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
          TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)
"""

devices = []      
for d in re.findall(r'^(\S+).*?inet addr:(\S+).*?Mask:(\S+)', ifconfig, re.S | re.M):
    devices.append((d[0], d[1], d[2]))

print devices

Outputs:

[('eth0', '10.244.21.118', '255.244.255.192')]

Finally, with a slight modification, you can have this loop through each device that appears when you run ifconfig. You would need one more for loop before the re.findall loop, to split it by device. I believe something like for dev in ifconfig.split('\n\n'): would properly split it by device.

Comments

1

Since ifconfig's output is predictable, regular expressions are not really needed. This code captures the output and parses just using the usual python string facilities:

from subprocess import check_output
lines = check_output(["/sbin/ifconfig", "eth0"]).split('\n')
line = lines[1] # Get the 2nd line
parts = line.split()
inet_addr = parts[2]
mask = parts[-1].split(':')[1]
print 'inet_addr=%s mask=%s' % (inet_addr, mask)

Comments

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.