Làm cách nào tôi có thể sử dụng Python để lấy tên máy chủ hệ thống?


679

Tôi đang viết một chương trình trò chuyện cho một mạng cục bộ. Tôi muốn có thể xác định máy tính và lấy tên máy tính do người dùng đặt bằng Python.

Câu trả lời:


1043

Sử dụng socketgethostname()chức năng của nó . Điều này sẽ nhận được hostnamemáy tính nơi trình thông dịch Python đang chạy:

import socket
print(socket.gethostname())

70
tốt, điều đó không đúng Nó hoạt động cho tôi ngoại tuyến và ở nhà, nhưng bây giờ tôi là một văn phòng và điều này trả về một tên máy chủ khác.
DataGreed

74
Và lưu ý rằng đối với FQDN bạn có thể sử dụngsocket.getfqdn()
Dave Forgac

31
@DataGreed đó là vì tên máy chủ của bạn đang thay đổi. Không phải vấn đề của trăn.
strickli

4
@DataGreed 1. Tôi khá chắc chắn đó không phải là "ngẫu nhiên", mặc dù nó có thể xuất hiện theo cách đó với bạn. 2. Câu hỏi cho biết "tên máy chủ hệ thống", không phải "tên hệ thống". 3. Đối với một số lượng lớn hệ thống (phải thừa nhận không bao gồm các cửa sổ), tên máy chủ và hệ thống là như nhau.
strickli

7
Chỉ cần tò mò sự khác biệt giữa socket.gethostname () và os.uname () [1] hay platform.uname () [1] là những gì
LetsOMG

387

Cả hai đều khá di động:

import platform
platform.node()

import socket
socket.gethostname()

Bất kỳ giải pháp sử dụng các biến môi trường HOSThoặc HOSTNAMEkhông phải là di động. Ngay cả khi nó hoạt động trên hệ thống của bạn khi bạn chạy nó, nó có thể không hoạt động khi chạy trong các môi trường đặc biệt như cron.


6
Vâng, bán di động. Trên một số nền tảng, platform.node () cung cấp cho fqdn và trên các nền tảng khác, chỉ có tên máy chủ
raindog308

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Bên dưới Radar

8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
Bên dưới Radar

7
@BelowtheRadar đừng lo lắng, tôi thường chỉ gọi một trong hai lần này cho mỗi tập lệnh.
robert

6
platform.node () thậm chí còn nhanh hơn os.getenv. gethostname thậm chí không phải là một ứng cử viên. Nhưng nếu thời gian không phải là một yếu tố: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]nên biến cross-platform và môi trường hỗ trợ nếu chúng tồn tại - mà cho phép một số điều khiển người dùng trong tình huống cấp thiết, ví dụ nhưHOSTNAME=correct python xyz.py
Orwellophile

121

Bạn có thể sẽ tải mô-đun os, vì vậy một đề xuất khác sẽ là:

import os
myhost = os.uname()[1]

8
+1 cho một giải pháp sử dụng osmô-đun. Không di động và không thực sự chính xác, nhưng dù sao cũng tiện dụng.
MestreLion

20
os.uname không được hỗ trợ trên Windows: docs.python.org/dev/library/os#os.uname
Noam Manos

9
Bạn cũng có thể thực hiện os.uname (). Node để làm cho nó rõ ràng hơn một chút trong 3.3+
Hut8

4
Một câu trả lời dưới đây cho giao diện tương tự platform.uname()[1], DOES hoạt động trên Windows.
tưởng tượng

6
@fantabolous Có lẽ bạn không nên sử dụng các từ định vị như "bên dưới" vì câu trả lời có thể đã thay đổi trong khi hạ cánh;)
Jonathan Komar

65

Thế còn :

import platform

h = platform.uname()[1]

Trên thực tế bạn có thể muốn có một cái nhìn cho tất cả các kết quả trong platform.uname()


1
Đã làm việc trên Ubuntu và Windows cho tôi. Cảm ơn! 👍
GollyJer

61

os.getenv('HOSTNAME')os.environ['HOSTNAME']không phải lúc nào cũng làm việc. Trong các công việc định kỳ và WSDL, HTTP HOSTNAME không được đặt. Sử dụng cái này thay thế:

import socket
socket.gethostbyaddr(socket.gethostname())[0]

Nó luôn luôn (ngay cả trên Windows) trả về một tên máy chủ đủ điều kiện, ngay cả khi bạn đã xác định một bí danh ngắn trong / etc / hosts .

Nếu bạn đã xác định một bí danh trong / etc / hosts thì socket.gethostname()sẽ trả về bí danh. platform.uname()[1]làm điều tương tự

Tôi gặp phải trường hợp trên không hoạt động. Đây là những gì tôi đang sử dụng bây giờ:

import socket
if socket.gethostname().find('.')>=0:
    name=socket.gethostname()
else:
    name=socket.gethostbyaddr(socket.gethostname())[0]

Đầu tiên, nó gọi gethostname để xem nếu nó trả về một cái gì đó trông giống như tên máy chủ, nếu không nó sử dụng giải pháp ban đầu của tôi.


15
bạn có thể muốn socket.getfqdn(), mặc dù đó không phải là những gì OP yêu cầu
jfs

17

Nếu tôi đúng, bạn đang tìm kiếm hàm socket.gethostname:

>> import socket
>> socket.gethostname()
'terminus'

13

Từ ít nhất trăn> = 3,3 :

Bạn có thể sử dụng trường nodenamevà tránh sử dụng lập chỉ mục mảng:

os.uname().nodename

Mặc dù, ngay cả tài liệu của os.uname cũng đề xuất sử dụngsocket.gethostname()



5

Trên một số hệ thống, tên máy chủ được đặt trong môi trường. Nếu đó là trường hợp của bạn, mô-đun os có thể kéo nó ra khỏi môi trường thông qua os.getenv . Ví dụ: nếu HOSTNAME là biến môi trường chứa những gì bạn muốn, thì sau đây sẽ có được nó:

import os
system_name = os.getenv('HOSTNAME')

Cập nhật: Như đã lưu ý trong các nhận xét, điều này không phải lúc nào cũng hoạt động, vì không phải môi trường của mọi người đều được thiết lập theo cách này. Tôi tin rằng tại thời điểm ban đầu tôi trả lời điều này, tôi đã sử dụng giải pháp này vì đó là điều đầu tiên tôi tìm thấy trong một tìm kiếm trên web và nó hoạt động với tôi vào thời điểm đó. Do thiếu tính di động, có lẽ tôi sẽ không sử dụng nó ngay bây giờ. Tuy nhiên, tôi để lại câu trả lời này cho mục đích tham khảo. FWIW, nó sẽ loại bỏ nhu cầu nhập khác nếu môi trường của bạn có tên hệ thống và bạn đã nhập mô-đun os. Kiểm tra nó - nếu nó không hoạt động trong tất cả các môi trường mà bạn mong đợi chương trình của mình hoạt động, hãy sử dụng một trong những giải pháp khác được cung cấp.


5
Điều đó trả về "Không" cho tôi. Theo liên kết bạn đã đăng, điều đó có nghĩa là biến 'HOSTNAME' không tồn tại ...: - /
John

@ John: Bạn có trên Windows không? Nó hoạt động với tôi trên một hộp Linux, nhưng tôi cũng không nhận được gì trên Windows.
GreenMatt

@MuhiaNJoroge: Tôi nghĩ rằng điều đó phụ thuộc vào việc triển khai / cài đặt của bạn. Khi tôi viết câu trả lời đó, tôi đã ở trên một chiếc hộp Red Hat và nó đã hoạt động. Bây giờ tôi đang dùng Ubuntu và nó không hoạt động. Tôi đã sửa đổi câu trả lời.
GreenMatt

Không làm việc trong NAS lenovo, không trả lại. Bây giờ tôi đang sử dụng bản in ổ cắm nhập khẩu (socket.gethostname ())
Rui Martins

@RuiMartins: Như tôi đã nói, nó dường như không hoạt động ở mọi nơi. Vui mừng bạn tìm thấy một cái gì đó hoạt động.
GreenMatt

5

Tôi cần tên của PC để sử dụng trong tệp conf PyLog của tôi và thư viện socket không khả dụng, nhưng thư viện os thì có.

Đối với Windows tôi đã sử dụng:

os.getenv('COMPUTERNAME', 'defaultValue')

Trong đó defaultValue là một chuỗi để ngăn Không trả lại


12
COMPUTERNAME là một biến môi trường duy nhất của Microsoft và không có tính di động.
Dwight Spencer

1
Có, nhưng nó hoạt động cho các hệ thống MS, và nếu nó phù hợp, nó hoạt động. Nhiều lần mọi người ở đây quá mải mê với tốc độ hoặc sự độc lập nền tảng khi tính thực tiễn và câu hỏi khiến họ không liên quan.
Bill Kidd

7
@BillKidd OP đề cập đến Windows, OS X và Linux trong câu hỏi, vì vậy cần tính di động của hệ thống là một giả định rất hợp lý.
zstewart

1
@BillKidd Mặc dù nói chung, đúng là bạn nên tránh tối ưu hóa sớm hoặc tính di động, không sử dụng một giải pháp có sẵn và có thể bảo trì nhiều hơn bởi vì nó dễ mang theo hơn.
Nhà vật lý điên

2

Bạn phải thực thi dòng mã này

sock_name = socket.gethostname()

Và sau đó bạn có thể sử dụng tên để tìm addr:

print(socket.gethostbyname(sock_name))
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.