1. ホーム
  2. python

[解決済み] PythonでNIC(ネットワークインターフェースコントローラ)からIPアドレスを取得するにはどうしたらいいですか?

2023-05-09 21:58:10

質問

Unix上のPythonスクリプトでエラーが発生した場合、メールが送信されます。

IP アドレスがテスト サーバーである 192.168.100.37 の場合、電子メールの件名に {テスト環境} を追加するよう依頼されました。この方法で、1 つのバージョンのスクリプトを用意し、電子メールがテスト サーバー上の混乱したデータから来ているかどうかを判断する方法を提供できます。

しかし、ググってみると、このようなコードを見つけることができます。

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

しかし、これではIPアドレスが127.0.1.1になってしまいます。私が 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を取得したのか分かりませんが、どちらにしても私が欲しいのはこれではないのです。ググると同じ構文に行き着きます。 Bash スクリプトやnetifaces、そして私は標準的なライブラリを使用しようとしています。

では、Pythonでeth0のIPアドレスを取得するにはどうすればいいのでしょうか?

どのように解決するのですか?

2つの方法があります。

方法その1(外部パッケージを利用する)

にバインドされている IP アドレスを問い合わせる必要があります。 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(外部パッケージなし)

pythonのパッケージを使わずに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