UnixのPythonスクリプトでエラーが発生すると、電子メールが送信されます。
IPアドレスがテストサーバーである192.168.100.37である場合、電子メールの件名に{Testing Environment}を追加するように求められました。このようにして、スクリプトの1つのバージョンと、テストサーバー上の混乱したデータから電子メールが送信されているかどうかを確認する方法を使用できます。
ただし、グーグルで検索すると、次のコードを見つけ続けます。
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を取得したかわかりませんが、どちらの方法でもそれは私が望むものではありません。私がグーグルで検索するとき、私は同じ構文 Bash scriptsまたはnetifacesを使い続け、標準ライブラリを使用しようとしています。
では、Pythonでeth0のIPアドレスを取得するにはどうすればよいですか?
2つの方法:
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()
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
または、名前を知らなくてもネットワークに接続するために使用されるインターフェイスの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質問Bashを使用してIPアドレスのみを取得するifconfigを解析)):
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()
または、コメントで@sergが指摘しているように、grepとawkの代わりにsplit()
を使用して、解析タスクの一部をpythonインタープリターにシフトできます。
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()
呼び出しによって返される配列の境界を確認する必要があります。
正規表現を使用した別のバージョン:
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 __== "__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]
実行中の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
それは私のために働いた
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の結果です:
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:~ $
これで、pythonに移動して次のことができます。
import os
mine = os.popen('ifconfig eth0 | grep "inet 192" | cut -c 14-25')
myip = mine.read()
print (myip)