Lorsqu'une erreur survient dans un script Python sous Unix, un courrier électronique est envoyé.
On m'a demandé d'ajouter {Testing Environment} à la ligne d'objet de l'e-mail si l'adresse IP est 192.168.100.37, qui est le serveur de test. De cette façon, nous pouvons avoir une version d'un script et un moyen de savoir si l'e-mail provient de données altérées sur le serveur de test.
Cependant, quand je recherche sur Google, je continue à trouver ce code
import socket
socket.gethostbyname(socket.gethostname())
Cependant, cela me donne l'adresse IP 127.0.1.1. Quand j'utilise ifconfig
je reçois ce
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)
Tout d'abord, je ne sais pas d'où il vient 127.0.1.1, mais de toute façon ce n'est pas ce que je veux. Quand je recherche sur Google, je continue à utiliser la même syntaxe, Bash scripts ou netifaces et j'essaie d'utiliser des bibliothèques standard.
Alors, comment puis-je obtenir l'adresse IP de eth0 en Python?
Deux méthodes:
Vous devez demander l'adresse IP liée à votre interface eth0
. Ceci est disponible à partir du paquet 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"
Vous pouvez également obtenir une liste de toutes les interfaces disponibles via
ni.interfaces()
Voici un moyen d'obtenir l'adresse IP sans utiliser de package python:
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'
Remarque: détecter l’adresse IP pour déterminer l’environnement que vous utilisez est un sacré bidouillage. Presque tous les frameworks fournissent un moyen très simple de définir/modifier une variable d'environnement pour indiquer l'environnement actuel. Essayez de consulter votre documentation à ce sujet. Cela devrait être aussi simple que de faire
if app.config['ENV'] == 'production':
#send production email
else:
#send development email
Sinon, si vous voulez obtenir l'adresse IP de l'interface utilisée pour vous connecter au réseau sans connaître son nom, vous pouvez utiliser ceci:
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]
Je sais que c'est un peu différent de votre question, mais d'autres peuvent arriver ici et trouver celle-ci plus utile. Vous n'avez pas besoin d'avoir un itinéraire vers 8.8.8.8 pour l'utiliser. Tout ce qu'il fait est d'ouvrir un socket, mais n'envoie aucune donnée.
Une approche simple qui renvoie une chaîne d'adresses IP pour les interfaces est la suivante:
from subprocess import check_output
ips = check_output(['hostname', '--all-ip-addresses'])
pour plus d'informations, voir hostname .
Si vous ne devez travailler que sous Unix, vous pouvez utiliser un appel système (réf. Question Stack Overflow Analyser ifconfig pour obtenir uniquement mon adresse IP à l'aide de Bash):
import os
f = os.popen('ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1')
your_ip=f.read()
Puisque la plupart des réponses utilisent ifconfig
pour extraire l'IPv4 de l'interface eth0, qui est déconseillée pour ip addr
, le code suivant pourrait être utilisé à la place:
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()
Sinon, vous pouvez déplacer une partie de la tâche d'analyse vers l'interpréteur python en utilisant split()
au lieu de grep et awk, comme le souligne @serg dans le commentaire:
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]
Mais dans ce cas, vous devez vérifier les limites du tableau renvoyé par chaque appel split()
.
Une autre version utilisant regex:
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]
essayez ci-dessous le code, cela fonctionne pour moi dans 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
S'appuyant sur la réponse de @jeremyjjbrown, une autre version qui nettoie après elle-même comme mentionné dans les commentaires de sa réponse Cette version permet également de fournir une adresse de serveur différente pour une utilisation sur des réseaux internes privés, etc.
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]
Recherchez l'adresse IP de la première entrée eth/wlan dans ifconfig qui est en cours d'exécution:
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
Ça a fonctionné pour moi
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
Encore une autre façon d’obtenir l’adresse IP d’une carte réseau en utilisant Python.
J'avais cela dans le cadre d'une application que j'avais développée il y a longtemps, et je ne voulais pas simplement faire git rm script.py
. Donc, je présente ici l'approche, en utilisant subprocess
et liste les compréhensions dans un souci d'approche fonctionnelle et moins de lignes de 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]
De plus, vous pouvez utiliser une approche similaire pour obtenir une liste de cartes réseau:
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
Voici la solution en tant que Gist .
Et vous auriez quelque chose comme ça:
$ 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'
C'est le résultat de 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:~ $
En coupant un peu la sortie, nous avons:
pi@raspberrypi:~ $
pi@raspberrypi:~ $ ifconfig eth0 | grep "inet 192" | cut -c 14-25
192.168.2.24
pi@raspberrypi:~ $
pi@raspberrypi:~ $
Maintenant, nous pouvons aller en python et faire:
import os
mine = os.popen('ifconfig eth0 | grep "inet 192" | cut -c 14-25')
myip = mine.read()
print (myip)