Tìm địa chỉ IP cục bộ bằng stdlib của Python


547

Làm cách nào tôi có thể tìm thấy địa chỉ IP cục bộ (ví dụ 192.168.xx hoặc 10.0.xx) trong nền tảng Python một cách độc lập và chỉ sử dụng thư viện chuẩn?


7
IP địa phương? Hoặc IP công cộng? Làm thế nào bạn sẽ đối phó với các hệ thống có nhiều IP?
Sargun Dhillon

sử dụng ifconfig -avà sử dụng đầu ra từ đó ...
Fredrik Pihl

16
@Fredrik Đó là một ý tưởng tồi. Trước hết, bạn không cần thiết phải thực hiện một quy trình mới và điều đó có thể ngăn chương trình của bạn hoạt động trong các cấu hình bị khóa chặt (hoặc, bạn sẽ phải cho phép các quyền mà chương trình của bạn không cần). Thứ hai, bạn sẽ giới thiệu các lỗi cho người dùng ở các địa phương khác nhau. Thứ ba, nếu bạn quyết định bắt đầu một chương trình mới, bạn không nên bắt đầu một chương trình không dùng nữa - ip addrphù hợp hơn nhiều (và dễ dàng hơn để phân tích, để khởi động).
phihag

12
@phihag bạn hoàn toàn chính xác, cảm ơn vì đã sửa chữa sự ngu ngốc của tôi
Fredrik Pihl

1
Một vấn đề cơ bản hơn ở đây là trong một chương trình mạng hiện đại được viết đúng, (các) địa chỉ IP cục bộ phụ thuộc vào mạng ngang hàng hoặc tập hợp các đồng nghiệp tiềm năng. Nếu địa chỉ IP cục bộ là cần thiết cho bindmột ổ cắm cho một giao diện cụ thể, thì đó là một vấn đề chính sách. Nếu địa chỉ IP cục bộ là cần thiết để trao nó cho một máy ngang hàng để máy ngang hàng có thể "gọi lại", tức là để mở một kết nối trở lại máy cục bộ, thì tình huống phụ thuộc vào việc có NAT (Dịch địa chỉ mạng) không hộp ở giữa. Nếu không có NAT, getsocknamelà một lựa chọn tốt.
Pekka Nikander

Câu trả lời:


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

Điều này sẽ không hoạt động luôn (trả 127.0.0.1về các máy có tên máy chủ /etc/hostsnhư 127.0.0.1), một cách viết tắt sẽ là những gì gimel hiển thị, sử dụng socket.getfqdn()thay thế. Tất nhiên máy của bạn cần một tên máy chủ có thể phân giải.


43
Bạn nên lưu ý rằng đây không phải là một giải pháp độc lập nền tảng. Rất nhiều Linux sẽ trả về 127.0.0.1 làm địa chỉ IP của bạn bằng phương thức này.
Jason Baker

20
Một biến thể: socket.gethostbyname (socket.getfqdn ())
gimel

55
Điều này dường như chỉ trả về một địa chỉ IP duy nhất. Nếu máy có nhiều địa chỉ thì sao?
Jason R. Coombs

26
Trên Ubuntu, điều này trả về 127.0.1.1 vì một số lý do.
slikts

13
@Jason R. Coombs, sử dụng mã sau đây để truy xuất danh sách các địa chỉ IPv4 thuộc về máy chủ:socket.gethostbyname_ex(socket.gethostname())[-1]
Barmaley

460

Tôi chỉ tìm thấy cái này nhưng có vẻ hơi hack, tuy nhiên họ nói đã thử nó trên * nix và tôi đã làm trên windows và nó đã hoạt động.

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()

Điều này giả định rằng bạn có quyền truy cập internet và không có proxy cục bộ.


31
Thật tuyệt nếu bạn có một vài giao diện trên máy và cần một giao diện để định tuyến, ví dụ như gmail.com
elzapp

4
Nó có thể là một ý tưởng tốt để bắt ngoại lệ socket.error có thể được tăng lên bởi s.connect ()!
phobie

39
Sẽ tốt hơn nếu sử dụng địa chỉ IP thay vì tên miền - nó phải nhanh hơn và độc lập với tính khả dụng của DNS. Ví dụ: chúng tôi có thể sử dụng 8.8.8.8 IP - Máy chủ DNS công cộng của Google.
wobmene

10
Rất thông minh, hoạt động hoàn hảo. Thay vì gmail hoặc 8.8.8.8, bạn cũng có thể sử dụng IP hoặc địa chỉ của máy chủ mà bạn muốn được nhìn thấy, nếu điều đó được áp dụng.
Hợp đồng của giáo sư Falken vi phạm

3
Ví dụ này có một sự phụ thuộc bên ngoài để có thể thực sự giải quyết gmail.com. Nếu bạn đặt nó thành một địa chỉ IP không nằm trên mạng cục bộ của bạn (không quan trọng nếu nó lên hay xuống) thì nó sẽ hoạt động mà không phụ thuộc và không có lưu lượng mạng.
nghiệt ngã

254

Phương thức này trả về IP "chính" trên hộp cục bộ (cái có tuyến mặc định) .

  • KHÔNG cần truy cập mạng có thể định tuyến hoặc bất kỳ kết nối nào cả.
  • Hoạt động ngay cả khi tất cả các giao diện được rút ra khỏi mạng.
  • KHÔNG cần hoặc thậm chí cố gắng để có được bất cứ nơi nào khác .
  • Hoạt động với NAT, công cộng, riêng tư, bên ngoài và IP nội bộ
  • Python thuần 2 (hoặc 3) không có phụ thuộc bên ngoài.
  • Hoạt động trên Linux, Windows và OSX.

Python 3 hoặc 2:

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

Điều này trả về một IP duy nhất là IP chính (một IP có tuyến mặc định). Thay vào đó, nếu bạn cần tất cả IP được gắn vào tất cả các giao diện (bao gồm localhost, v.v.), hãy xem câu trả lời này .

Nếu bạn đứng sau tường lửa NAT như hộp wifi của bạn ở nhà, thì điều này sẽ không hiển thị IP NAT công cộng của bạn, mà thay vào đó là IP riêng của bạn trên mạng cục bộ có tuyến mặc định tới bộ định tuyến WIFI cục bộ của bạn; nhận IP bên ngoài của bộ định tuyến wifi của bạn sẽ yêu cầu chạy cái này trên hộp THAT hoặc kết nối với một dịch vụ bên ngoài như whatismyip.com/whatismyipaddress.com có ​​thể phản hồi lại IP ... nhưng điều đó hoàn toàn khác với câu hỏi ban đầu. :)


7
Hoạt động trong Raspbian với Python 2 và 3!
pierce.jason

3
Xuất sắc. Hoạt động trên Win7,8,8.1 + Linux Mint & Arch, bao gồm cả VM.
shermy

2
Hoạt động trong Windows 10 Pro! Cảm ơn bạn, Jamieson Becker!
varantes

3
Vì một số lý do, điều này không hoạt động trên Mac OS X El Capitan 10.11.6 (nó tạo ra lỗi hệ điều hành ngoại lệ: [Errno 49] Không thể gán địa chỉ được yêu cầu). Thay đổi cổng từ '0' thành '1': s.connect (('10.255.255.255', 1)) hoạt động với tôi trên cả Mac OS X và Linux Ubuntu 17.04
Pedro Scarapicchia Junior

10
Đây phải là câu trả lời được chấp nhận. socket.gethostbyname(socket.gethostname())cho kết quả khủng khiếp.
Jason Floyd

142

Như một bí danh được gọi myip, nó sẽ hoạt động ở mọi nơi:

alias myip="python -c 'import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(\"127.\")][:1], [[(s.connect((\"8.8.8.8\", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])'"
  • Hoạt động chính xác với Python 2.x, Python 3.x, các bản phân phối Linux hiện đại và cũ, OSX / macOS và Windows để tìm địa chỉ IPv4 hiện tại.
  • Sẽ không trả về kết quả chính xác cho các máy có nhiều địa chỉ IP, IPv6, không có địa chỉ IP được định cấu hình hoặc không có truy cập internet.

Tương tự như trên, nhưng chỉ có mã Python:

import socket
print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
  • Điều này sẽ đưa ra một ngoại lệ nếu không có địa chỉ IP được cấu hình.

Phiên bản cũng sẽ hoạt động trên mạng LAN mà không cần kết nối internet:

import socket
print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])

(cảm ơn @ccpizza )


Lý lịch :

Việc sử dụng socket.gethostbyname(socket.gethostname())không hoạt động ở đây, bởi vì một trong những máy tính tôi đang sử dụng /etc/hostscó các mục và tham chiếu trùng lặp với chính nó. socket.gethostbyname()chỉ trả về mục cuối cùng trong/etc/hosts .

Đây là nỗ lực ban đầu của tôi, loại bỏ tất cả các địa chỉ bắt đầu bằng "127.":

import socket
print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])

Điều này hoạt động với Python 2 và 3, trên Linux và Windows, nhưng không xử lý một số thiết bị mạng hoặc IPv6. Tuy nhiên, nó đã ngừng hoạt động trên các bản phát hành Linux gần đây, vì vậy tôi đã thử kỹ thuật thay thế này. Nó cố gắng kết nối với máy chủ DNS của Google 8.8.8.8tại cổng 53:

import socket
print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])

Sau đó, tôi đã kết hợp hai kỹ thuật trên thành một lớp lót có thể hoạt động ở mọi nơi và tạo ra myipbí danh và đoạn mã Python ở đầu câu trả lời này.

Với sự phổ biến ngày càng tăng của IPv6 và đối với các máy chủ có nhiều giao diện mạng, sử dụng mô-đun Python của bên thứ ba để tìm địa chỉ IP có lẽ vừa mạnh mẽ vừa đáng tin cậy hơn bất kỳ phương pháp nào được liệt kê ở đây.


2
@Alexander: Chỉ cần nói rằng câu trả lời này ít hữu ích hơn nhiều so với trước đây (và nó không giống như việc lọc ra các bản sao là một vấn đề lớn;). Theo tài liệu socket.getaddrinfo()nên hoạt động ổn định trên các nền tảng - nhưng tôi chỉ kiểm tra nó trên Linux, không bận tâm về bất kỳ hệ điều hành nào khác.
Wladimir Palant

1
@Alexander /etc/resolve.conf: No such file or directoryvà tôi có địa chỉ IPv4 cục bộ được hiển thị bởi ifconfig.
anatoly techtonik

2
Tôi có thể xác nhận rằng phiên bản cập nhật hoạt động với Ubuntu 14.04 với cả Python2 và Py3k.
Uli Köhler

4
"Cập nhật" hiển thị một mẹo hay với kết nối () trên ổ cắm UDP. Nó không gửi lưu lượng nhưng cho phép bạn tìm địa chỉ người gửi cho các gói đến người nhận được chỉ định. Cổng có khả năng không liên quan (thậm chí 0 nên hoạt động). Trên một máy chủ đa năng, điều quan trọng là chọn một địa chỉ trong mạng con bên phải.
Peter Hansen

17
chỉ vì bạn có thể viết mã đó trên một dòng, điều đó không có nghĩa là bạn nên ...
JackLeo

91

Bạn có thể sử dụng mô-đun netifaces . Chỉ loại:

pip install netifaces

trong shell lệnh của bạn và nó sẽ tự cài đặt trên cài đặt Python mặc định.

Sau đó, bạn có thể sử dụng nó như thế này:

from netifaces import interfaces, ifaddresses, AF_INET
for ifaceName in interfaces():
    addresses = [i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr':'No IP addr'}] )]
    print '%s: %s' % (ifaceName, ', '.join(addresses))

Trên máy tính của tôi, nó được in:

{45639BDC-1050-46E0-9BE9-075C30DE1FBC}: 192.168.0.100
{D43A468B-F3AE-4BF9-9391-4863A4500583}: 10.5.9.207

Tác giả của mô-đun này tuyên bố nó sẽ hoạt động trên Windows, UNIX và Mac OS X.


20
Như đã nêu trong câu hỏi tôi muốn một cái gì đó từ cài đặt mặc định, vì không cần cài đặt thêm.
UnkwnTech

4
Đây sẽ là câu trả lời yêu thích của tôi, ngoại trừ việc các mạng không hỗ trợ IPv6 trên Windows và dường như không rõ ràng. Có ai tìm ra cách lấy địa chỉ IPv6 trên Windows chưa?
Jean-Paul Calderone

3
netifaces không hỗ trợ py3k và yêu cầu trình biên dịch C là PITA trên windows.
Matt Tham gia

4
@MattJoiner Cả hai điều này đều không còn đúng nữa (phiên bản mới nhất có mã nhị phân Windows trên PyPI và không hỗ trợ Py3K).
alastair

4
@ Jean-PaulCalderone FWIW, phiên bản mới nhất của mạng không hỗ trợ IPv6 trên Windows.
alastair

47

Phương pháp API socket

xem https://stackoverflow.com/a/28950776/711085

Nhược điểm:

  • Không đa nền tảng.
  • Yêu cầu nhiều mã dự phòng hơn, gắn liền với sự tồn tại của các địa chỉ cụ thể trên internet
  • Điều này cũng sẽ không hoạt động nếu bạn đứng sau NAT
  • Có thể tạo kết nối UDP, không độc lập với tính khả dụng DNS (thường là của ISP) (xem các câu trả lời khác cho các ý tưởng như sử dụng máy chủ 8.8.8.8: của Google (trùng hợp là DNS))
  • Đảm bảo rằng bạn đặt địa chỉ đích KHÔNG THỂ DÙNG, giống như một địa chỉ IP số được đảm bảo cụ thể để không được sử dụng. KHÔNG sử dụng một số tên miền như fakesubdomain.google.com hoặc somefakewebsite.com; bạn vẫn sẽ gửi thư rác cho bên đó (hiện tại hoặc trong tương lai) và cũng sẽ spam các hộp mạng của riêng bạn.

Phương pháp phản xạ

(Xin lưu ý rằng điều này không trả lời câu hỏi của OP về địa chỉ IP cục bộ, ví dụ 192.168 ...; nó cung cấp cho bạn địa chỉ IP công cộng của bạn, có thể được mong muốn hơn tùy theo trường hợp sử dụng.)

Bạn có thể truy vấn một số trang web như whatismyip.com (nhưng với API), chẳng hạn như:

from urllib.request import urlopen
import re
def getPublicIp():
    data = str(urlopen('http://checkip.dyndns.com/').read())
    # data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'

    return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)

hoặc nếu sử dụng python2:

from urllib import urlopen
import re
def getPublicIp():
    data = str(urlopen('http://checkip.dyndns.com/').read())
    # data = '<html><head><title>Current IP Check</title></head><body>Current IP Address: 65.96.168.198</body></html>\r\n'

    return re.compile(r'Address: (\d+\.\d+\.\d+\.\d+)').search(data).group(1)

Ưu điểm:

  • Một ưu điểm của phương pháp này là nó đa nền tảng
  • Nó hoạt động từ phía sau NAT xấu xí (ví dụ: bộ định tuyến nhà của bạn).

Nhược điểm (và cách giải quyết):

  • Yêu cầu trang web này phải được nâng cấp, định dạng không thay đổi (gần như chắc chắn sẽ không) và các máy chủ DNS của bạn sẽ hoạt động. Người ta có thể giảm thiểu vấn đề này bằng cách truy vấn các bộ phản xạ địa chỉ IP của bên thứ ba khác trong trường hợp không thành công.
  • Vectơ tấn công có thể xảy ra nếu bạn không truy vấn nhiều gương phản xạ (để ngăn phản xạ bị xâm phạm nói với bạn rằng địa chỉ của bạn không phải là địa chỉ) hoặc nếu bạn không sử dụng HTTPS (để ngăn chặn cuộc tấn công trung gian giả vờ trở thành máy chủ)

chỉnh sửa : Mặc dù ban đầu tôi nghĩ các phương pháp này thực sự tồi tệ (trừ khi bạn sử dụng nhiều dự phòng, mã có thể không liên quan trong nhiều năm kể từ bây giờ), nó đặt ra câu hỏi "Internet là gì?". Một máy tính có thể có nhiều giao diện trỏ đến nhiều mạng khác nhau. Để biết mô tả kỹ hơn về chủ đề này, google chogateways and routes. Một máy tính có thể truy cập mạng nội bộ thông qua một cổng nội bộ hoặc truy cập web trên toàn thế giới thông qua một cổng ví dụ như một bộ định tuyến (thường là trường hợp). Địa chỉ IP cục bộ mà OP yêu cầu chỉ được xác định rõ đối với một lớp liên kết duy nhất, vì vậy bạn phải chỉ định rằng ("đó là card mạng hay cáp ethernet mà chúng ta đang nói đến?") . Có thể có nhiều câu trả lời không độc đáo cho câu hỏi này như được đặt ra. Tuy nhiên, địa chỉ IP toàn cầu trên web trên toàn thế giới có thể được xác định rõ (trong trường hợp không có sự phân mảnh mạng lớn): có thể là đường dẫn trở lại qua cổng có thể truy cập TLD.


Điều này sẽ trả về địa chỉ toàn mạng LAN của bạn nếu bạn đứng sau NAT. Nếu bạn đang kết nối với Internet, bạn có thể kết nối với một dịch vụ web trả về một trong những địa chỉ IP công cộng của bạn.
phihag

Nó không tạo kết nối TCP vì nó tạo kết nối UDP.
Anuj Gupta

2
Thay thế trong phiên bản API của ổ cắm, hãy thay thế s.connect (('CHERTN MỘT SỐ MỤC TIÊU WEBSITE.com', 0)) bằng s.setsockopt (socket.SOL_SOCKET, socket.SO_BROADCAST, 1); s.connect (('<) quảng bá> ', 0)) để tránh tra cứu DNS. (Tôi đoán có thể có vấn đề với việc phát sóng nếu có tường lửa)
dlm

45

Nếu máy tính có tuyến đến Internet, điều này sẽ luôn hoạt động để có được địa chỉ IP cục bộ ưa thích, ngay cả khi / etc / hosts không được đặt chính xác.

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 1))  # connect() for UDP doesn't send packets
local_ip_address = s.getsockname()[0]

Cái này hoạt động ra sao ? , 8.8.8.8là một máy chủ google dns chúng ta có thể làm điều đó với một máy chủ dns cục bộ không?
Ciasto piekarz

39

Trên Linux:

>>> import socket, struct, fcntl
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sockfd = sock.fileno()
>>> SIOCGIFADDR = 0x8915
>>>
>>> def get_ip(iface = 'eth0'):
...     ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
...     try:
...         res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
...     except:
...         return None
...     ip = struct.unpack('16sH2x4s8x', res)[2]
...     return socket.inet_ntoa(ip)
... 
>>> get_ip('eth0')
'10.80.40.234'
>>> 

Vì vậy, điều này có hiệu quả mở một ổ cắm mà nó không làm gì và bạn kiểm tra dữ liệu thô về ổ cắm đó để lấy IP cục bộ?
Dave

1
Ổ cắm được mở để có được một fd để giao tiếp với kernel (thông qua ioctl). Ổ cắm không bị ràng buộc giao diện mà bạn muốn có thông tin bổ sung về nó - nó chỉ là một cơ chế giao tiếp giữa không gian người dùng và kernel. vi.wikipedia.org/wiki/Ioctl lxr.free-electrons.com/source/net/socket.c
tMC

2
Hoạt động trên Python3 với một sửa đổi: struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)nên được thay thế bằngstruct.pack('16sH14s', iface.encode('utf-8'), socket.AF_INET, b'\x00'*14)
pepoluan

1
@ChristianFischer ioctllà một giao diện cũ mà tôi không tin là hỗ trợ IPv6 và có thể sẽ không bao giờ có. Tôi nghĩ rằng cách 'Phải' là thông qua Netlink, điều này không đơn giản trong Python. Tôi nghĩ libc nên có chức năng getifaddrscó thể được truy cập thông qua ctypesmô-đun pythons có thể hoạt động - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC

1
@Maddy ioctl là một giao diện cũ mà tôi không tin là hỗ trợ IPv6 và có thể sẽ không bao giờ có. Tôi nghĩ rằng cách 'Phải' là thông qua Netlink, điều này không đơn giản trong Python. Tôi nghĩ libc nên có chức năng getifaddrs có thể được truy cập thông qua mô-đun ctypes của pythons có thể hoạt động - man7.org/linux/man-pages/man3/getifaddrs.3.html
tMC

27

tôi đang sử dụng mô-đun sau:

#!/usr/bin/python
# module for getting the lan ip address of the computer

import os
import socket

if os.name != "nt":
    import fcntl
    import struct
    def get_interface_ip(ifname):
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        return socket.inet_ntoa(fcntl.ioctl(
                s.fileno(),
                0x8915,  # SIOCGIFADDR
                struct.pack('256s', bytes(ifname[:15], 'utf-8'))
                # Python 2.7: remove the second argument for the bytes call
            )[20:24])

def get_lan_ip():
    ip = socket.gethostbyname(socket.gethostname())
    if ip.startswith("127.") and os.name != "nt":
        interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
        for ifname in interfaces:
            try:
                ip = get_interface_ip(ifname)
                break;
            except IOError:
                pass
    return ip

Đã thử nghiệm với windows và linux (và không yêu cầu các mô-đun bổ sung cho những thứ đó) dành cho sử dụng trên các hệ thống trong một mạng LAN dựa trên IPv4.

Danh sách cố định tên giao diện không hoạt động cho các phiên bản linux gần đây, đã áp dụng thay đổi systemd v197 liên quan đến tên giao diện có thể dự đoán được như Alexander chỉ ra . Trong những trường hợp như vậy, bạn cần thay thế danh sách theo cách thủ công bằng tên giao diện trên hệ thống của bạn hoặc sử dụng một giải pháp khác như mạng .


2
Điều này không tương thích với các tên giao diện Linux dự đoán mới, chẳng hạn như enp0s25. Để biết thêm thông tin, hãy xem wiki.archlinux.org/index.php/Network_Configuration#Device_names
Alexander

2
Tôi đã sử dụng python 3.4 và phần 'struct.pack (...)' cần được thay đổi thành 'struct.pack (' 256s ', byte (ifname [: 15],' utf-8 '))'. Xem câu hỏi này: stackoverflow.com/q/27391167/76010
Bakanekobrain 6/03/2015

1
trên Raspbian w / Python 2.7.3 - byte () không thích đối số thứ 2. Nhưng điều này đã làm việc: struct.pack('256s', bytes(ifname[:15]))
colm.anseo

24

Tôi sử dụng cái này trên các máy ubfox của mình:

import commands
commands.getoutput("/sbin/ifconfig").split("\n")[1].split()[1][5:]

Điều này không hoạt động.


Đẹp và đơn giản. Cũng hoạt động trên Linux AMI của Amazon, nhưng chỉ khi tôi root. Nếu không, tôi sẽ gặp lỗi: 'sh: ifconfig: không tìm thấy lệnh'
IgorGanapolsky

Vì vậy, bạn nên sử dụng "/ sbin / ifconfig" như gavaletz đã nói. Nó cũng hoạt động trên Red Hat 4.1.2-48.
IgorGanapolsky

7
Không dùng nữa kể từ 2.6. Sử dụng mô đun quy trình con để chạy các lệnh.
Colin Dunklau 18/03/13

5
Và ifconfig cũng không được dùng nữa. Sử dụng iproute2.
Helmut Grohne

Nhận tất cả các ips: nhập khẩu sh; [ip.split () [1] [5:] cho ip trong bộ lọc (lambda x: 'inet addr' trong x, sh.ifconfig (). split ("\ n"))]
Gabriel Littman

20

Nếu bạn không muốn sử dụng các gói bên ngoài và không muốn dựa vào các máy chủ Internet bên ngoài, điều này có thể hữu ích. Đó là một mẫu mã mà tôi tìm thấy trên Google Code Search và được sửa đổi để trả về thông tin bắt buộc:

def getIPAddresses():
    from ctypes import Structure, windll, sizeof
    from ctypes import POINTER, byref
    from ctypes import c_ulong, c_uint, c_ubyte, c_char
    MAX_ADAPTER_DESCRIPTION_LENGTH = 128
    MAX_ADAPTER_NAME_LENGTH = 256
    MAX_ADAPTER_ADDRESS_LENGTH = 8
    class IP_ADDR_STRING(Structure):
        pass
    LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
    IP_ADDR_STRING._fields_ = [
        ("next", LP_IP_ADDR_STRING),
        ("ipAddress", c_char * 16),
        ("ipMask", c_char * 16),
        ("context", c_ulong)]
    class IP_ADAPTER_INFO (Structure):
        pass
    LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
    IP_ADAPTER_INFO._fields_ = [
        ("next", LP_IP_ADAPTER_INFO),
        ("comboIndex", c_ulong),
        ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
        ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
        ("addressLength", c_uint),
        ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
        ("index", c_ulong),
        ("type", c_uint),
        ("dhcpEnabled", c_uint),
        ("currentIpAddress", LP_IP_ADDR_STRING),
        ("ipAddressList", IP_ADDR_STRING),
        ("gatewayList", IP_ADDR_STRING),
        ("dhcpServer", IP_ADDR_STRING),
        ("haveWins", c_uint),
        ("primaryWinsServer", IP_ADDR_STRING),
        ("secondaryWinsServer", IP_ADDR_STRING),
        ("leaseObtained", c_ulong),
        ("leaseExpires", c_ulong)]
    GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
    GetAdaptersInfo.restype = c_ulong
    GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
    adapterList = (IP_ADAPTER_INFO * 10)()
    buflen = c_ulong(sizeof(adapterList))
    rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
    if rc == 0:
        for a in adapterList:
            adNode = a.ipAddressList
            while True:
                ipAddr = adNode.ipAddress
                if ipAddr:
                    yield ipAddr
                adNode = adNode.next
                if not adNode:
                    break

Sử dụng:

>>> for addr in getIPAddresses():
>>>    print addr
192.168.0.100
10.5.9.207

Vì nó dựa vào windll, điều này sẽ chỉ hoạt động trên Windows.


Các giải pháp lót ở trên thường hoạt động trên các cửa sổ. Đó là Linux, đó là một vấn đề.
ricree

14
+1 Kỹ thuật này ít nhất là cố gắng trả về tất cả các địa chỉ trên máy.
Jason R. Coombs

1
Kịch bản này không thành công trên máy của tôi sau khi trả lại địa chỉ đầu tiên. Lỗi là đối tượng "AttributionError: 'LP_IP_ADDR_STRING' không có thuộc tính 'ipAddress'" Tôi nghi ngờ nó có liên quan đến địa chỉ IPv6.
Jason R. Coombs

1
Hóa ra vấn đề là đối với bất cứ điều gì ngoại trừ địa chỉ IP đầu tiên, adNode không bị hủy đăng ký. Thêm một dòng nữa vào ví dụ trong vòng lặp while và nó hoạt động với tôi: adNode = adNode.contents
Jason R. Coombs

18

Trên Debian (đã thử nghiệm) và tôi nghi ngờ hầu hết Linux ..

import commands

RetMyIP = commands.getoutput("hostname -I")

Trên MS Windows (đã kiểm tra)

import socket

socket.gethostbyname(socket.gethostname())

1
Không hoạt động trên macOS:hostname: illegal option -- I\nusage: hostname [-fs] [name-of-host]
Derek 朕 會

18

Một phiên bản tôi không tin rằng đã được đăng. Tôi đã thử nghiệm với python 2.7 trên Ubuntu 12.04.

Tìm thấy giải pháp này tại: http://code.activestate.com/recipes/439094-get-the-ip-address-associated-with-a-network-inter/

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

Kết quả ví dụ:

>>> get_ip_address('eth0')
'38.113.228.130'

2
Hoạt động trên Python3, Ubuntu 18.04; Chuỗi cần phải là byte: >>> socket.inet_ntoa (fcntl.ioctl (s.fileno (), 0x8915, struct.pack ('256s', 'enp0s31f6' [: 15] .encode ('utf-8') )) [20:24]) '192.168.1.1'
giám khảo

12

Sự thay đổi về câu trả lời của ninjagecko. Điều này sẽ hoạt động trên bất kỳ mạng LAN nào cho phép phát sóng UDP và không yêu cầu quyền truy cập vào một địa chỉ trên mạng LAN hoặc internet.

import socket
def getNetworkIp():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    s.connect(('<broadcast>', 0))
    return s.getsockname()[0]

print (getNetworkIp())

Đợi đã, <broadcast>tên máy chủ hợp lệ như thế nào ? !! Có bao nhiêu loại tên máy chủ bằng lời nói là hợp lệ?
Dev Aggarwal

Điều này hoạt động với tôi trên Ubuntu 20.04 - nhận 192.168.0.24 chứ không phải 127.0.0.1
Lewis Morris

8

Tôi e rằng không có cách nào độc lập với nền tảng tốt để thực hiện việc này ngoài việc kết nối với máy tính khác và để nó gửi cho bạn địa chỉ IP của bạn. Ví dụ: findmyipaddress . Lưu ý rằng điều này sẽ không hoạt động nếu bạn cần một địa chỉ IP phía sau NAT trừ khi máy tính bạn đang kết nối cũng đứng sau NAT.

Đây là một giải pháp hoạt động trong Linux: lấy địa chỉ IP được liên kết với giao diện mạng .


8

Một cách đơn giản để tạo đầu ra "sạch" thông qua các tiện ích dòng lệnh:

import commands
ips = commands.getoutput("/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " +
                         "awk {'print $2'} | sed -ne 's/addr\:/ /p'")
print ips

Nó sẽ hiển thị tất cả các địa chỉ IPv4 trên hệ thống.


1
Nó sẽ không hiển thị tất cả các địa chỉ IPv4, bởi vì ifconfig chỉ cho bạn biết về các địa chỉ chính. Bạn cần sử dụng "ip" từ iproute2 để xem tất cả các địa chỉ.
Helmut Grohne

Đó là một địa ngục của rất nhiều vỏ cho một câu hỏi yêu cầu thư viện chuẩn. Ngoài ra, phân tích cú pháp ifconfig không phải là di động và thậm chí sẽ không hoạt động đáng tin cậy trên một máy.
Dominik George

7

FYI Tôi có thể xác minh rằng phương pháp:

import socket
addr = socket.gethostbyname(socket.gethostname())

Hoạt động trong OS X (10.6,10.5), Windows XP và trên máy chủ của bộ phận RHEL được quản lý tốt. Nó không hoạt động trên máy ảo CentOS tối thiểu mà tôi chỉ thực hiện một số hack nhân. Vì vậy, trong trường hợp đó, bạn chỉ cần kiểm tra địa chỉ 127.0.0.1 và trong trường hợp đó, hãy làm như sau:

if addr == "127.0.0.1":
     import commands
     output = commands.getoutput("/sbin/ifconfig")
     addr = parseaddress(output)

Và sau đó phân tích địa chỉ IP từ đầu ra. Cần lưu ý rằng ifconfig không có trong PATH của người dùng thông thường theo mặc định và đó là lý do tại sao tôi đưa ra đường dẫn đầy đủ trong lệnh. Tôi hi vọng cái này giúp được.


7

Đây là một biến thể của câu trả lời của UnkwnTech - nó cung cấp một get_local_addr()hàm, trả về địa chỉ IP LAN chính của máy chủ. Tôi đang đăng nó vì điều này bổ sung thêm một số điều: hỗ trợ ipv6, xử lý lỗi, bỏ qua addrs localhost / linklocal và sử dụng addr TESTNET (rfc5737) để kết nối.

# imports
import errno
import socket
import logging

# localhost prefixes
_local_networks = ("127.", "0:0:0:0:0:0:0:1")

# ignore these prefixes -- localhost, unspecified, and link-local
_ignored_networks = _local_networks + ("0.", "0:0:0:0:0:0:0:0", "169.254.", "fe80:")

def detect_family(addr):
    if "." in addr:
        assert ":" not in addr
        return socket.AF_INET
    elif ":" in addr:
        return socket.AF_INET6
    else:
        raise ValueError("invalid ipv4/6 address: %r" % addr)

def expand_addr(addr):
    """convert address into canonical expanded form --
    no leading zeroes in groups, and for ipv6: lowercase hex, no collapsed groups.
    """
    family = detect_family(addr)
    addr = socket.inet_ntop(family, socket.inet_pton(family, addr))
    if "::" in addr:
        count = 8-addr.count(":")
        addr = addr.replace("::", (":0" * count) + ":")
        if addr.startswith(":"):
            addr = "0" + addr
    return addr

def _get_local_addr(family, remote):
    try:
        s = socket.socket(family, socket.SOCK_DGRAM)
        try:
            s.connect((remote, 9))
            return s.getsockname()[0]
        finally:
            s.close()
    except socket.error:
        # log.info("trapped error connecting to %r via %r", remote, family, exc_info=True)
        return None

def get_local_addr(remote=None, ipv6=True):
    """get LAN address of host

    :param remote:
        return  LAN address that host would use to access that specific remote address.
        by default, returns address it would use to access the public internet.

    :param ipv6:
        by default, attempts to find an ipv6 address first.
        if set to False, only checks ipv4.

    :returns:
        primary LAN address for host, or ``None`` if couldn't be determined.
    """
    if remote:
        family = detect_family(remote)
        local = _get_local_addr(family, remote)
        if not local:
            return None
        if family == socket.AF_INET6:
            # expand zero groups so the startswith() test works.
            local = expand_addr(local)
        if local.startswith(_local_networks):
            # border case where remote addr belongs to host
            return local
    else:
        # NOTE: the two addresses used here are TESTNET addresses,
        #       which should never exist in the real world.
        if ipv6:
            local = _get_local_addr(socket.AF_INET6, "2001:db8::1234")
            # expand zero groups so the startswith() test works.
            if local:
                local = expand_addr(local)
        else:
            local = None
        if not local:
            local = _get_local_addr(socket.AF_INET, "192.0.2.123")
            if not local:
                return None
    if local.startswith(_ignored_networks):
        return None
    return local

Tôi nghĩ rằng đây có thể là một câu trả lời thực sự tốt .. nhưng nó luôn trở lạiNone
Jamie Lindsey

@JamieLindsey Bạn có một số chi tiết về hệ điều hành, cấu hình mạng của bạn không? Ngoài ra, những gì như get_local_addr(remove="www.google.com")trở lại? Ghi nhật ký được socket.errorném bởi _get_local_addr () có thể giúp chẩn đoán.
Eli Collins

6
import socket
[i[4][0] for i in socket.getaddrinfo(socket.gethostname(), None)]

1
Hmm ... trên một máy chủ có hai NIC, điều này cung cấp một trong các địa chỉ IP được gán, nhưng được lặp lại ba lần. Trên máy tính xách tay của tôi, nó cho '127.0.1.1' (lặp lại ba lần ...) ...
bryn

Cung cấp cho tôi ['fe80::34e8:fe19:1459:2cde%22','fe80::d528:99fb:d572:e289%12', '192.168.56.1', '192.168.1.2']trên máy tính để bàn Windows.
Nakilon

5

Điều này sẽ hoạt động trên hầu hết các hộp linux:

import socket, subprocess, re
def get_ipv4_address():
    """
    Returns IP address(es) of current machine.
    :return:
    """
    p = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE)
    ifc_resp = p.communicate()
    patt = re.compile(r'inet\s*\w*\S*:\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
    resp = patt.findall(ifc_resp[0])
    print resp

get_ipv4_address()

5

Câu trả lời này là nỗ lực cá nhân của tôi để giải quyết vấn đề lấy IP LAN, vì socket.gethostbyname(socket.gethostname())cũng trả về 127.0.0.1. Phương pháp này không yêu cầu Internet chỉ cần kết nối mạng LAN. Mã dành cho Python 3.x nhưng có thể dễ dàng được chuyển đổi cho 2.x. Sử dụng phát sóng UDP:

import select
import socket
import threading
from queue import Queue, Empty

def get_local_ip():
        def udp_listening_server():
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.bind(('<broadcast>', 8888))
            s.setblocking(0)
            while True:
                result = select.select([s],[],[])
                msg, address = result[0][0].recvfrom(1024)
                msg = str(msg, 'UTF-8')
                if msg == 'What is my LAN IP address?':
                    break
            queue.put(address)

        queue = Queue()
        thread = threading.Thread(target=udp_listening_server)
        thread.queue = queue
        thread.start()
        s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        waiting = True
        while waiting:
            s2.sendto(bytes('What is my LAN IP address?', 'UTF-8'), ('<broadcast>', 8888))
            try:
                address = queue.get(False)
            except Empty:
                pass
            else:
                waiting = False
        return address[0]

if __name__ == '__main__':
    print(get_local_ip())

1
Điều gì xảy ra nếu bạn chạy đồng thời trên hai máy trên cùng một mạng? Khi bạn phát tin nhắn của mình trên mạng, tất cả các máy sẽ nhận được 'Địa chỉ IP LAN của tôi là gì. Udp_listening_server của bạn có thể trả lời 'địa chỉ IP của bạn là xxx' cho tin nhắn.
Nicolas Defranoux

4

127.0.1.1 địa chỉ IP thực của bạn. Nói chung hơn, một máy tính có thể có bất kỳ số lượng địa chỉ IP. Bạn có thể lọc chúng cho các mạng riêng - 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12 và 192.168.0.0/16.

Tuy nhiên, không có cách nào đa nền tảng để có được tất cả các địa chỉ IP. Trên Linux, bạn có thể sử dụng SIOCGIFCONFioctl.


2
Anh ta có nghĩa là IP nhìn thấy bên ngoài của mình. Phạm vi 127. *. *. * Thường đề cập đến localhost hoặc mạng nội bộ, đây rõ ràng không phải là thứ anh ta muốn.
Cerin

4

Một sàng lọc nhỏ của phiên bản lệnh sử dụng lệnh IP và trả về địa chỉ IPv4 và IPv6:

import commands,re,socket

#A generator that returns stripped lines of output from "ip address show"
iplines=(line.strip() for line in commands.getoutput("ip address show").split('\n'))

#Turn that into a list of IPv4 and IPv6 address/mask strings
addresses1=reduce(lambda a,v:a+v,(re.findall(r"inet ([\d.]+/\d+)",line)+re.findall(r"inet6 ([\:\da-f]+/\d+)",line) for line in iplines))
#addresses1 now looks like ['127.0.0.1/8', '::1/128', '10.160.114.60/23', 'fe80::1031:3fff:fe00:6dce/64']

#Get a list of IPv4 addresses as (IPstring,subnetsize) tuples
ipv4s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if '.' in addr)]
#ipv4s now looks like [('127.0.0.1', 8), ('10.160.114.60', 23)]

#Get IPv6 addresses
ipv6s=[(ip,int(subnet)) for ip,subnet in (addr.split('/') for addr in addresses1 if ':' in addr)]

4

Bạn có thể sử dụng lệnh "ip route" trên GNU / Linux để biết địa chỉ IP hiện tại của bạn.

Điều này cho thấy IP được cung cấp cho giao diện bởi máy chủ DHCP đang chạy trên bộ định tuyến / modem. Thông thường "192.168.1.1/24" là IP cho mạng cục bộ trong đó "24" có nghĩa là phạm vi địa chỉ IP rõ ràng được cung cấp bởi máy chủ DHCP trong phạm vi mặt nạ.

Đây là một ví dụ: Lưu ý rằng PyNotify chỉ là một bổ sung để giúp tôi hiểu rõ hơn và hoàn toàn không bắt buộc

#! /usr/bin/env python

import sys , pynotify

if sys.version_info[1] != 7:
   raise RuntimeError('Python 2.7 And Above Only')       

from subprocess import check_output # Available on Python 2.7+ | N/A 

IP = check_output(['ip', 'route'])
Split_Result = IP.split()

# print Split_Result[2] # Remove "#" to enable

pynotify.init("image")
notify = pynotify.Notification("Ip", "Server Running At:" + Split_Result[2] , "/home/User/wireless.png")    
notify.show()    

Ưu điểm của việc này là bạn không cần chỉ định giao diện mạng. Điều đó khá hữu ích khi chạy một máy chủ ổ cắm

Bạn có thể cài đặt PyNotify bằng easy_install hoặc thậm chí Pip:

easy_install py-notify

hoặc là

pip install py-notify

hoặc trong tập lệnh / trình thông dịch python

from pip import main

main(['install', 'py-notify'])

4

Nếu bạn đang tìm kiếm một địa chỉ IPV4 khác với địa chỉ IP localhost của bạn 127.0.0.1, thì đây là một đoạn mã python gọn gàng:

import subprocess
address = subprocess.check_output(['hostname', '-s', '-I'])
address = address.decode('utf-8') 
address=address[:-1]

Mà cũng có thể được viết trong một dòng duy nhất:

address = subprocess.check_output(['hostname', '-s', '-I']).decode('utf-8')[:-1]

Ngay cả khi bạn đặt localhostvào /etc/hostname, mã vẫn sẽ cung cấp địa chỉ IP cục bộ của bạn.


4

Đối với Linux, bạn chỉ có thể sử dụng check_outputcác hostname -Ilệnh hệ thống như vậy:

from subprocess import check_output
check_output(['hostname', '-I'])

đối với nhân viên Google, tôi biết câu hỏi dành cho giải pháp đa nền tảng
Kasper Skytte Andersen

3

Lưu ý: Đây không phải là sử dụng thư viện tiêu chuẩn, nhưng khá đơn giản.

$ pip cài đặt pif

from pif import get_public_ip
get_public_ip()

3
các câu hỏi là về việc tìm IP bằng stdlib
Alexandru Chirila

3

netifaces có sẵn thông qua pip và easy_install. (Tôi biết, nó không ở trong cơ sở, nhưng nó có thể đáng để cài đặt.)

netifaces có một số điểm kỳ lạ trên các nền tảng:

  • Giao diện localhost / loop-back có thể không luôn luôn được bao gồm (Cygwin).
  • Địa chỉ được liệt kê trên mỗi giao thức (ví dụ: IPv4, IPv6) và các giao thức được liệt kê trên mỗi giao diện. Trên một số hệ thống (Linux), mỗi cặp giao diện giao thức có giao diện liên kết riêng (sử dụng ký hiệu interface_name: n) trong khi trên các hệ thống khác (Windows), một giao diện sẽ có một danh sách địa chỉ cho mỗi giao thức. Trong cả hai trường hợp đều có một danh sách giao thức, nhưng nó có thể chỉ chứa một phần tử duy nhất.

Đây là một số mã mạng để chơi với:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
# Note: Can't filter for 'lo' here because Windows lacks it.
ifaces = netifaces.interfaces()

# Get all addresses (of all kinds) for each interface
if_addrs = [netifaces.ifaddresses(iface) for iface in ifaces]

# Filter for the desired address type
if_inet_addrs = [addr[PROTO] for addr in if_addrs if PROTO in addr]

iface_addrs = [s['addr'] for a in if_inet_addrs for s in a if 'addr' in s]
# Can filter for '127.0.0.1' here.

Đoạn mã trên không ánh xạ một địa chỉ trở lại tên giao diện của nó (hữu ích để tạo quy tắc ebtables / iptables khi đang di chuyển). Vì vậy, đây là một phiên bản giữ thông tin trên với tên giao diện trong một tuple:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
ifaces = netifaces.interfaces()

# Get addresses for each interface
if_addrs = [(netifaces.ifaddresses(iface), iface) for iface in ifaces]

# Filter for only IPv4 addresses
if_inet_addrs = [(tup[0][PROTO], tup[1]) for tup in if_addrs if PROTO in tup[0]]

iface_addrs = [(s['addr'], tup[1]) for tup in if_inet_addrs for s in tup[0] if 'addr' in s]

Và, không, tôi không yêu thích việc hiểu danh sách. Đó chỉ là cách bộ não của tôi hoạt động những ngày này.

Đoạn mã sau sẽ in ra tất cả:

from __future__ import print_function  # For 2.x folks
from pprint import pprint as pp

print('\nifaces = ', end='')
pp(ifaces)

print('\nif_addrs = ', end='')
pp(if_addrs)

print('\nif_inet_addrs = ', end='')
pp(if_inet_addrs)

print('\niface_addrs = ', end='')
pp(iface_addrs)

Thưởng thức!


netifaces thực sự làm giảm cuộc sống rất nhiều trong khi xử lý vấn đề này.
Drake Guan

3

Phiên bản Python 3.4 sử dụng gói asyncio mới được giới thiệu.

async get_local_ip():
    loop = asyncio.get_event_loop()
    transport, protocol = await loop.create_datagram_endpoint(
        asyncio.DatagramProtocol,
        remote_addr=('8.8.8.8', 80))
    result = transport.get_extra_info('sockname')[0])
    transport.close()
    return result

Điều này dựa trên câu trả lời tuyệt vời của UnkwnTech .


3

Để lấy địa chỉ IP, bạn có thể sử dụng lệnh shell trực tiếp trong python :

import socket, subprocess

def getIpAndHostname():
    hostname =  socket.gethostname()

    shell_cmd = "ifconfig | awk '/inet addr/{print substr($2,6)}'"
    proc = subprocess.Popen([shell_cmd], stdout=subprocess.PIPE, shell=True)
    (out, err) = proc.communicate()

    ip_list = out.split('\n')
    ip = ip_list[0]

    for _ip in ip_list:
        try:
            if _ip != "127.0.0.1" and _ip.split(".")[3] != "1":
                ip = _ip
        except:
            pass
    return ip, hostname

ip_addr, hostname = getIpAndHostname()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.