Programing

Python의 NIC에서 IP 주소를 얻으려면 어떻게해야합니까?

lottogame 2020. 11. 29. 09:29
반응형

Python의 NIC에서 IP 주소를 얻으려면 어떻게해야합니까?


Unix의 Python 스크립트에서 오류가 발생하면 이메일이 전송됩니다.

테스트 서버 인 IP 주소가 192.168.100.37이면 이메일 제목에 {Testing Environment}를 추가하라는 요청을 받았습니다. 이렇게하면 한 가지 버전의 스크립트와 이메일이 테스트 서버의 엉망인 데이터에서 오는지 알 수 있습니다.

그러나 Google에서 계속이 코드를 찾습니다.

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

그러나 그것은 나에게 127.0.1.1의 IP 주소를 제공합니다. 내가 사용할 때 나는 ifconfig이것을 얻는다

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)

첫째, 127.0.1.1이 어디에서 왔는지 모르겠지만 어느 쪽이든 내가 원하는 것이 아닙니다. Google에서 동일한 구문, Bash 스크립트 또는 netifaces를 계속 사용하고 표준 라이브러리를 사용하려고합니다.

그렇다면 파이썬에서 eth0의 IP 주소를 어떻게 얻을 수 있습니까?


두 가지 방법 :

방법 # 1 (외부 패키지 사용)

eth0인터페이스에 바인딩 된 IP 주소를 요청해야합니다 . 이것은 netifaces 패키지 에서 사용할 수 있습니다.

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

다음을 통해 사용 가능한 모든 인터페이스 목록을 얻을 수도 있습니다.

ni.interfaces()

방법 # 2 (외부 패키지 없음)

다음은 파이썬 패키지를 사용하지 않고 IP 주소를 얻는 방법입니다.

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'

참고 : 사용중인 환경을 확인하기 위해 IP 주소를 감지하는 것은 해킹입니다. 거의 모든 프레임 워크는 현재 환경을 나타 내기 위해 환경 변수를 설정 / 수정하는 매우 간단한 방법을 제공합니다. 이에 대한 문서를 살펴보십시오. 하는 것만 큼 간단해야합니다.

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

또는 이름을 몰라도 네트워크에 연결하는 데 사용되는 인터페이스의 IP 주소를 얻으려면 다음을 사용할 수 있습니다.

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]

귀하의 질문과 약간 다른 점을 알고 있지만 다른 사람들이 여기에 도착하여이 질문이 더 유용하다고 생각할 수 있습니다. 이것을 사용하기 위해 8.8.8.8에 대한 경로가 필요하지 않습니다. 그것이하는 일은 소켓을 여는 것이지만 데이터를 보내지 않는 것입니다.


인터페이스에 대한 IP 주소가있는 문자열을 반환하는 간단한 방법은 다음과 같습니다.

from subprocess import check_output

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

자세한 내용은 hostname을 참조하십시오 .


Unix에서만 작업해야하는 경우 시스템 호출을 사용할 수 있습니다 (참조. Stack Overflow question Parse ifconfig to get only my IP address using Bash ) :

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

대부분의 답변 ifconfig은 eth0 인터페이스에서 IPv4를 추출하는 데 사용 되므로을 위해 더 이상 사용되지 않으므로 ip addr대신 다음 코드를 사용할 수 있습니다.

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

최신 정보:

또는 split()@serg가 주석에서 지적했듯이 grep 및 awk 대신 사용하여 구문 분석 작업의 일부를 파이썬 인터프리터 로 이동할 수 있습니다.

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]

그러나이 경우 각 split()호출에서 반환 된 배열의 경계를 확인해야합니다 .

업데이트 2 :

정규식을 사용하는 다른 버전 :

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]

아래 코드를 시도해보십시오. Mac10.10.2에서 저에게 효과적입니다.

import subprocess

if __name__ == "__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

@jeremyjjbrown의 답변을 바탕으로 그의 답변에 대한 의견에서 언급했듯이 자체적으로 정리되는 또 다른 버전입니다. 이 버전은 또한 사설 내부 네트워크 등에 사용할 다른 서버 주소를 제공 할 수 있습니다.

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]

그것은 나를 위해 일했습니다

 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

실행중인 ifconfig에서 첫 번째 eth / wlan 항목의 IP 주소를 찾습니다.

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

이것은 ifconfig의 결과입니다.

pi@raspberrypi:~ $ 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

pi@raspberrypi:~ $ 

출력을 조금 잘라 내면 다음과 같습니다.

pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ ifconfig eth0 | grep "inet 192" | cut -c 14-25
192.168.2.24
pi@raspberrypi:~ $ 
pi@raspberrypi:~ $ 

이제 우리는 파이썬으로 가서 다음을 수행 할 수 있습니다.

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

Python을 사용하여 NIC에서 IP 주소를 얻는 또 다른 방법입니다.

I had this as part of an app that I developed long time ago, and I didn't wanted to simply git rm script.py. So, here I provide the approach, using subprocess and list comprehensions for the sake of functional approach and less lines of code:

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]

Additionally, you can use a similar approach for obtaining a list of NICs:

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                                                

Here's the solution as a Gist.

And you would have something like this:

$ 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'

참고URL : https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-from-nic-in-python

반응형