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

681

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

Джон
источник

Ответы:

1043

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

import socket
print(socket.gethostname())
Alex
источник
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]
mike0042
источник
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
17

Если я прав, вы ищете функцию socket.gethostname:

>> import socket
>> socket.gethostname()
'terminus'
конечная станция
источник
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. Проверьте это - если он не работает во всех средах, в которых вы ожидаете, что ваша программа будет работать, используйте одно из других предоставленных решений.

GreenMatt
источник
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))
Parzifal Kali
источник