Как я могу использовать Python, чтобы получить системное имя хоста?


681

Я пишу программу чата для локальной сети. Я хотел бы иметь возможность идентифицировать компьютеры и получить установленное пользователем имя компьютера с помощью Python.

Ответы:


1043

Использование socketи его gethostname()функциональность. Это получит hostnameкомпьютер, на котором работает интерпретатор Python:

import socket
print(socket.gethostname())

70
ну это не правильно. Это работает для меня в автономном режиме и дома, но теперь я офис, и это возвращает другое имя хоста.
DataGreed

74
И обратите внимание, что для полного доменного имени вы можете использоватьsocket.getfqdn()
Дейв Forgac

31
@DataGreed это потому, что ваше имя хоста меняется. Не проблема питона.
strickli

4
@ DataGreed 1. Я вполне уверен, что это не «случайный», хотя это может показаться вам таким. 2. В вопросе сказано «имя хоста системы», а не «имя системы». 3. Для большого количества систем (по общему признанию, не включая windows) имена хостов и систем совпадают.
strickli

8
Просто любопытно, в чем разница между socket.gethostname () и os.uname () [1] или platform.uname () [1]
LetsOMG

388

Оба они довольно портативны:

import platform
platform.node()

import socket
socket.gethostname()

Любые решения, использующие переменные HOSTили HOSTNAMEпеременные среды, не являются переносимыми. Даже если он работает в вашей системе при запуске, он может не работать при работе в особых средах, таких как cron.


6
Ну, полупортативный. На некоторых платформах platform.node () выдает fqdn, а на других - только имя хоста
raindog308

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
ниже радара

8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
ниже радара

7
@ BelowtheRadar не волнуйтесь, я обычно вызываю любой из них один раз для сценария.
Роберт

6
platform.node () даже быстрее, чем os.getenv. gethostname даже не претендент. Но если время не является фактором: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]должно быть кроссплатформенным и поддерживать переменные среды, если они существуют - что позволяет некоторый пользовательский контроль в неотложных обстоятельствах, напримерHOSTNAME=correct python xyz.py
Orwellophile

121

Вы, вероятно, все равно загрузите модуль os, поэтому другим предложением будет:

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

8
+1 за решение с использованием osмодуля. Не портативный и не очень точный, но в любом случае удобный.
MestreLion

20
os.uname не поддерживается в Windows: docs.python.org/dev/library/os#os.uname
Noam Manos

9
Вы также можете сделать os.uname (). Nodename, чтобы сделать его немного более очевидным в 3.3+
Hut8

4
Ответ ниже дает похожий вид platform.uname()[1], который работает на Windows.
Фантабол

6
@fantabolous Вы, вероятно, не должны использовать позиционные слова, такие как «ниже», так как ответы могли сместиться во время приземления;)
Джонатан Комар

65

Что о :

import platform

h = platform.uname()[1]

На самом деле вы можете посмотреть на все результаты в platform.uname()


1
Работал на Ubuntu и Windows для меня. Спасибо! 👍
GollyJer

61

os.getenv('HOSTNAME')и os.environ['HOSTNAME']не всегда работает. В заданиях cron и WSDL HTTP HOSTNAME не установлен. Используйте это вместо:

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

Он всегда (даже в Windows) возвращает полное имя хоста, даже если вы определили короткий псевдоним в / etc / hosts .

Если вы определили псевдоним в / etc / hosts, он socket.gethostname()вернет псевдоним.platform.uname()[1]делает то же самое.

Я столкнулся с случаем, когда вышеописанное не сработало. Это то, что я использую сейчас:

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

Сначала он вызывает gethostname, чтобы увидеть, возвращает ли он что-то, похожее на имя хоста, если нет, то использует мое оригинальное решение.


15
Вы, вероятно, хотите socket.getfqdn(), хотя это не то, что просит ОП
jfs


13

По крайней мере, Python> = 3.3 :

Вы можете использовать поле nodenameи избегать индексации массива:

os.uname().nodename

Хотя даже документация os.uname предлагает использоватьsocket.gethostname()



5

В некоторых системах имя хоста задается в среде. Если это так, то модуль os может вытащить его из среды через os.getenv . Например, если HOSTNAME является переменной окружения, содержащей то, что вы хотите, то получите следующее:

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

Обновление: как отмечено в комментариях, это не всегда работает, так как не все настроены таким образом. Я полагаю, что в то время, когда я первоначально отвечал на это, я использовал это решение, поскольку это было первое, что я нашел в веб-поиске, и оно работало для меня в то время. Из-за отсутствия мобильности я бы, наверное, не использовал это сейчас. Однако я оставляю этот ответ для справочных целей. FWIW, он устраняет необходимость в других операциях импорта, если ваша среда имеет системное имя и вы уже импортируете модуль os. Проверьте это - если он не работает во всех средах, в которых вы ожидаете, что ваша программа будет работать, используйте одно из других предоставленных решений.


5
Это возвращает «Нет» для меня. Согласно размещенной вами ссылке, это означает, что переменная 'HOSTNAME' не существует ...: - /
John

@John: ты на Windows? У меня это работало на Linux-боксе, но в Windows у меня тоже нет.
GreenMatt

@MuhiaNJoroge: Я думаю, это зависит от вашей реализации / установки. Когда я написал этот ответ, я был на коробке Red Hat, и это сработало. Сейчас я на Ubuntu, и это не работает. Я изменил ответ.
GreenMatt

Не работает в леново NAS, вернуть нет. Теперь я использую импорт сокетов печати (socket.gethostname ())
Руи Мартинс

@RuiMartins: Как я уже сказал, похоже, это не везде работает. Рад, что вы нашли то, что работает.
GreenMatt

5

Мне нужно было имя ПК для использования в моем файле конфигурации PyLog, и библиотека сокетов не доступна, но библиотека ОС есть.

Для Windows я использовал:

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

Где defaultValue - строка, чтобы предотвратить возвращение None


12
COMPUTERNAME - это переменная только для Microsoft, поэтому она не переносима.
Дуайт Спенсер

1
Да, но он работает для систем MS, и если он подходит, он работает. Много раз люди здесь слишком увязли в скорости или независимости от платформы, когда практичность и вопрос делают их неуместными.
Билл Кидд

7
@BillKidd OP упоминает о Windows, OS X и Linux, поэтому необходимость переносимости системы является очень разумным предположением.
zstewart

1
@BillKidd Хотя в целом верно то, что вам следует избегать преждевременной оптимизации или переносимости, не используя легкодоступное и, возможно, более удобное в обслуживании решение, поскольку оно более переносимо и ведет к противоположной противоположности.
Безумный физик

2

Вы должны выполнить эту строку кода

sock_name = socket.gethostname()

И тогда вы можете использовать имя, чтобы найти адрес:

print(socket.gethostbyname(sock_name))
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.