it-swarm.com.de

Wie kann ich die IP-Adresse von eth0 in Python erhalten?

Wenn ein Fehler in einem Python-Skript unter Unix auftritt, wird eine E-Mail gesendet.

Ich wurde gebeten, {Betreffumgebung} zur Betreffzeile der E-Mail hinzuzufügen, wenn die IP-Adresse 192.168.100.37 ist, die den Testserver darstellt. Auf diese Weise haben wir eine Version eines Skripts und eine Möglichkeit, um herauszufinden, ob die E-Mail von fehlerhaften Daten auf dem Testserver stammt.

Wenn ich jedoch google finde, finde ich diesen Code immer wieder:

import socket
socket.gethostbyname(socket.gethostname())

Das gibt mir jedoch die IP-Adresse 127.0.1.1. Wenn ich ifconfig verwende, bekomme ich das

eth0      Link encap:Ethernet  HWaddr 00:1c:c4:2c:c8:3e
          inet addr:192.168.100.37  Bcast:192.168.100.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:75760697 errors:0 dropped:411180 overruns:0 frame:0
          TX packets:23166399 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:59525958247 (59.5 GB)  TX bytes:10142130096 (10.1 GB)
          Interrupt:19 Memory:f0500000-f0520000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:25573544 errors:0 dropped:0 overruns:0 frame:0
          TX packets:25573544 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:44531490070 (44.5 GB)  TX bytes:44531490070 (44.5 GB)

Erstens weiß ich nicht, woher 127.0.1.1 stammt, aber so oder so will ich es nicht. Wenn ich google gehe, komme ich immer wieder zur gleichen Syntax, Bash - Skripten oder Netifaces, und versuche, Standardbibliotheken zu verwenden.

Wie kann ich die IP-Adresse von eth0 in Python erhalten?

54
Memor-X

Zwei Methoden:

Methode # 1 (externes Paket verwenden)

Sie müssen nach der IP-Adresse fragen, die an Ihre eth0-Schnittstelle gebunden ist. Dies ist im netifaces-Paket verfügbar

import netifaces as ni
ni.ifaddresses('eth0')
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print ip  # should print "192.168.100.37"

Sie können auch eine Liste aller verfügbaren Schnittstellen über erhalten

ni.interfaces()

Methode 2 (kein externes Paket)

So erhalten Sie die IP-Adresse, ohne ein Python-Paket zu verwenden:

import socket
import fcntl
import struct

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

get_ip_address('eth0')  # '192.168.0.110'

Hinweis: Das Erkennen der IP-Adresse zum Ermitteln der verwendeten Umgebung ist ein ziemlicher Hacker. Fast alle Frameworks bieten eine sehr einfache Möglichkeit, eine Umgebungsvariable festzulegen/zu ändern, um die aktuelle Umgebung anzuzeigen. Probieren Sie dazu Ihre Dokumentation aus. Es sollte so einfach sein wie zu tun

if app.config['ENV'] == 'production':
  #send production email
else:
  #send development email
143
Martin Konecny

Wenn Sie alternativ die IP-Adresse der Schnittstelle erhalten möchten, über die eine Verbindung zum Netzwerk hergestellt wird, ohne dessen Namen zu kennen, können Sie Folgendes verwenden:

import socket
def get_ip_address():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    return s.getsockname()[0]

Ich weiß, es ist ein bisschen anders als Ihre Frage, aber andere kommen hier an und finden diese hier nützlicher. Sie müssen dafür keine Route nach 8.8.8.8 haben. Es wird lediglich ein Socket geöffnet, es werden jedoch keine Daten gesendet.

88
jeremyjjbrown

Ein einfacher Ansatz, der einen String mit IP-Adressen für die Schnittstellen zurückgibt, ist:

from subprocess import check_output

ips = check_output(['hostname', '--all-ip-addresses'])

weitere Informationen finden Sie unter Hostname .

24
Alexander

Wenn Sie nur mit Unix arbeiten müssen, können Sie einen Systemaufruf verwenden (siehe Stapelüberlauf-Frage Parse ifconfig, um nur meine IP-Adresse über Bash zu erhalten):

import os
f = os.popen('ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1')
your_ip=f.read()
15
olmerg

Da die meisten Antworten ifconfig verwenden, um das IPv4 aus der eth0-Schnittstelle zu extrahieren, was zugunsten von ip addr veraltet ist, kann stattdessen folgender Code verwendet werden:

import os

ipv4 = os.popen('ip addr show eth0 | grep "\<inet\>" | awk \'{ print $2 }\' | awk -F "/" \'{ print $1 }\'').read().strip()
ipv6 = os.popen('ip addr show eth0 | grep "\<inet6\>" | awk \'{ print $2 }\' | awk -F "/" \'{ print $1 }\'').read().strip()

AKTUALISIEREN:

Alternativ können Sie einen Teil der Parsing-Aufgabe in den Python-Interpreter verschieben, indem Sie split() anstelle von grep und awk verwenden, wie @serg im Kommentar erläutert:

import os

ipv4 = os.popen('ip addr show eth0').read().split("inet ")[1].split("/")[0]
ipv6 = os.popen('ip addr show eth0').read().split("inet6 ")[1].split("/")[0]

In diesem Fall müssen Sie jedoch die Grenzen des Arrays überprüfen, die von jedem Aufruf von split() zurückgegeben werden.

UPDATE 2:

Eine andere Version, die Regex verwendet:

import os
import re

ipv4 = re.search(re.compile(r'(?<=inet )(.*)(?=\/)', re.M), os.popen('ip addr show eth0').read()).groups()[0]
ipv6 = re.search(re.compile(r'(?<=inet6 )(.*)(?=\/)', re.M), os.popen('ip addr show eth0').read()).groups()[0]
14

versuche den folgenden Code, es funktioniert für mich in Mac10.10.2:

import subprocess

if __== "__main__":
    result = subprocess.check_output('ifconfig en0 |grep -w inet', Shell=True) # you may need to use eth0 instead of en0 here!!!
    print 'output = %s' % result.strip()
    # result = None
    ip = ''
    if result:
        strs = result.split('\n')
        for line in strs:
            # remove \t, space...
            line = line.strip()
            if line.startswith('inet '):
                a = line.find(' ')
                ipStart = a+1
                ipEnd = line.find(' ', ipStart)
                if a != -1 and ipEnd != -1:
                    ip = line[ipStart:ipEnd]
                    break
    print 'ip = %s' % ip
2
xiaoweiz

Aufbauend auf der Antwort von @jeremyjjbrown, einer anderen Version, die sich selbst aufräumt, wie in den Kommentaren zu seiner Antwort erwähnt. Diese Version ermöglicht auch die Angabe einer anderen Serveradresse für die Verwendung in privaten internen Netzwerken usw.

import socket

def get_my_ip_address(remote_server="google.com"):
    """
    Return the/a network-facing IP number for this system.
    """
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: 
        s.connect((remote_server, 80))
        return s.getsockname()[0]
1
Steve Cohen

Suchen Sie die IP-Adresse des ersten eth/wlan-Eintrags in ifconfig, der RUNNING ist:

import itertools
import os
import re

def get_ip():
    f = os.popen('ifconfig')
    for iface in [' '.join(i) for i in iter(lambda: list(itertools.takewhile(lambda l: not l.isspace(),f)), [])]:
        if re.findall('^(eth|wlan)[0-9]',iface) and re.findall('RUNNING',iface):
            ip = re.findall('(?<=inet\saddr:)[0-9\.]+',iface)
            if ip:
                return ip[0]
    return False
0
Giles Greenway

Es hat für mich funktioniert 

 import subprocess
 my_ip = subprocess.Popen(['ifconfig eth0 | awk "/inet /" | cut -d":" -f 2 | cut -d" " -f1'], stdout=subprocess.PIPE, Shell=True)
 (IP,errors) = my_ip.communicate()
 my_ip.stdout.close()
 print IP
0
Abhijit

Eine weitere Möglichkeit, die IP-Adresse mithilfe von Python von einer Netzwerkkarte abzurufen.

Ich hatte dies als Teil einer App, die ich vor langer Zeit entwickelt habe, und ich wollte nicht einfach git rm script.py. Hier stelle ich den Ansatz mit subprocess und Listenverständnissen vor, um einen funktionalen Ansatz und weniger Codezeilen zu ermöglichen:

import subprocess as sp

__version__ = "v1.0"                                                            
__author__ = "@ivanleoncz"

def get_nic_ipv4(nic):                                                          
    """
        Get IP address from a NIC.                                              

        Parameter
        ---------
        nic : str
            Network Interface Card used for the query.                          

        Returns                                                                 
        -------                                                                 
        ipaddr : str
            Ipaddress from the NIC provided as parameter.                       
    """                                                                         
    result = None                                                               
    try:                                                                        
        result = sp.check_output(["ip", "-4", "addr", "show", nic],             
                                                  stderr=sp.STDOUT)
    except Exception:
        return "Unkown NIC: %s" % nic
    result = result.decode().splitlines()
    ipaddr = [l.split()[1].split('/')[0] for l in result if "inet" in l]        
    return ipaddr[0]

Darüber hinaus können Sie einen ähnlichen Ansatz zum Abrufen einer Liste von Netzwerkkarten verwenden:

def get_nics():                                                                 
    """                                                                         
        Get all NICs from the Operating System.                                 

        Returns                                                                 
        -------                                                                 
        nics : list                                                             
            All Network Interface Cards.                                        
    """                                                                         
    result = sp.check_output(["ip", "addr", "show"])                            
    result = result.decode().splitlines()                                       
    nics = [l.split()[1].strip(':') for l in result if l[0].isdigit()]          
    return nics                                                

Hier ist die Lösung als Gist .

Und du hättest so etwas:

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> 
>>> import helpers
>>> 
>>> helpers.get_nics()
['lo', 'enp1s0', 'wlp2s0', 'docker0']
>>> helpers.get_nic_ipv4('docker0')
'172.17.0.1'
>>> helpers.get_nic_ipv4('docker2')
'Unkown NIC: docker2'
0
ivanleoncz

Dies ist das Ergebnis von ifconfig:

[email protected]:~ $ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.24  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::88e9:4d2:c057:2d5f  prefixlen 64  scopeid 0x20<link>
        ether b8:27:eb:d0:9a:f3  txqueuelen 1000  (Ethernet)
        RX packets 261861  bytes 250818555 (239.1 MiB)
        RX errors 0  dropped 6  overruns 0  frame 0
        TX packets 299436  bytes 280053853 (267.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<Host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 74  bytes 16073 (15.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 74  bytes 16073 (15.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether b8:27:eb:85:cf:a6  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[email protected]:~ $ 

Wenn wir die Ausgabe etwas kürzen, haben wir:

[email protected]:~ $ 
[email protected]:~ $ ifconfig eth0 | grep "inet 192" | cut -c 14-25
192.168.2.24
[email protected]:~ $ 
[email protected]:~ $ 

Jetzt können wir zu Python gehen und Folgendes tun:

import os
mine = os.popen('ifconfig eth0 | grep "inet 192" | cut -c 14-25')
myip = mine.read()
print (myip)
0
Omar Cruz