0

This snippet gets me the dotted quad of my BSD network interface. I would like to figure out how to use the subprocess module instead.

ifcfg_lines = os.popen("/sbin/ifconfig fxp0").readlines()
x = string.split(ifcfg_lines[3])[1]

Seems as if I can't use subprocess in exactly the same way. I don't think I want shell=True or PIPE. What should I do to make the output indexable?

Thanks.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
mr.zog
  • 533
  • 1
  • 7
  • 26

2 Answers2

1
from subprocess import Popen, PIPE

ifcfg_lines = Popen("/sbin/ifconfig fxp0",shell=True,stdout=PIPE).stdout.readlines()
x = string.split(ifcfg_lines[3])[1]

For a little more elegance, hide the details:

def getBSDIP():
   from subprocess import Popen, PIPE
   import string

   CURRENT = Popen("/sbin/ifconfig fxp0", shell=True,stdout=PIPE).stdout.readlines()
   return(string.split(CURRENT[3])[1]) 

If you are going to use subprocess to do this then elegance is a bit limited because you are essentially doing something like screenscraping, except here you are scriptscraping. If you want a truly general solution, use the socket library, i.e. let Python handle the portability.

Often, when you look at a bit of code and you wish that there was a better cleaner way to do it, this means that you need to question your assumptions, and change the algorithm or architecture of the solution.

Michael Dillon
  • 31,973
  • 6
  • 70
  • 106
  • Uh. Yeah. I don't seem to have a PIPE module. Where the hell does PIPE come from? – mr.zog Oct 20 '09 at 00:39
  • http://docs.python.org/library/subprocess.html talks about "stdin=PIPE and stdout=PIPE must be specified." So I do specify them and python doesn't know wtf I'm talking about :) – mr.zog Oct 20 '09 at 00:45
  • `from subprocess import Popen,PIPE` – John La Rooy Oct 20 '09 at 00:45
  • Really? Why should I need to specify it? Rhetorical question. I know you are not Guido. – mr.zog Oct 20 '09 at 00:48
  • 1
    CURRENT = Popen("/sbin/ifconfig fxp0", shell=True,stdout=PIPE).stdout.readlines() This works and x = string.split(CURRENT[3])[1] can now get the correct IP address. But is there a more elegant way? – mr.zog Oct 20 '09 at 00:53
  • you should use something like lines, errors = Popen(['/sbin/ifconfig', 'fxp0'],....).communicate(). Otherwise you can catch a sigpipe on a long program output and introduce incorrectly quoted arguments. – abbot Oct 20 '09 at 21:59
0

Why not use something like:

import socket
ipadr = socket.gethostbyname(socket.gethostname())

as in Finding Local IP Addresses in Python and remove the subprocess dependency? There are also some other suggestions in that question.

I also found a post on the netifaces package that does aims to do this with better cross-platform support.

Community
  • 1
  • 1
Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
  • Heh. I was using the socket module in a less elegant way but discovered that I was getting the wrong IP back because of DNS. The server is a domestic broadband network client so DNS is going to be wrong unless my dyndns.org hostname is resolving correctly which it is not. – mr.zog Oct 20 '09 at 00:18
  • Fair enough, I wondered if that was why you were getting the ip by device name. How about the netifaces approach? It uses system calls instead of dns. – Dana the Sane Oct 20 '09 at 00:20
  • I had been doing this: CURRENT = socket.getaddrinfo(socket.gethostname(), None)[0][4][0] For whatever reason, the above (and your) syntax gets back 173.48.208.152 while /sbin/ifconfig fxp0 renders: 173.48.204.168 . – mr.zog Oct 20 '09 at 00:22
  • I am not familiar with netifaces. – mr.zog Oct 20 '09 at 00:25