Як я можу використовувати Python для отримання імені системи хоста?


681

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

Відповіді:


1043

Використання socketта його gethostname()функціональність. Це отримає hostnameкомп'ютер, де працює інтерпретатор Python:

import socket
print(socket.gethostname())

70
ну це не правильно. Він працює для мене в режимі офлайн і вдома, але зараз я в офісі, і це повертає інше ім’я хоста.
DataGreed

74
І зауважте, що для FQDN ви можете використовуватиsocket.getfqdn()
Дейв Форгач

31
@DataGreed тому, що ім’я вашого хоста змінюється. Не проблема пітона.
strickli

4
@DataGreed 1. Я впевнений, що це не є "випадковим", хоча це може здатися саме вам. 2. У запитанні було вказано "ім'я хоста системи", а не "ім'я системи". 3. Для великої кількості систем (правда, не враховуючи вікон) імена хостів і систем однакові.
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

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. Перевірте це - якщо вона працює не у всіх середовищах, в яких ви очікуєте, що ваша програма працюватиме, використовуйте одне з інших наданих рішень.


5
Це повертає для мене "Ні". Згідно з посиланням, яке ви опублікували, це означає, що змінної "HOSTNAME" не існує ...: - /
Джон

@John: Ти в Windows? Це працювало для мене на вікні Linux, але я також не отримую None на Windows.
GreenMatt

@MuhiaNJoroge: Я думаю, що це залежить від вашої реалізації / установки. Коли я написав цю відповідь, я опинився на коробці Red Hat, і це спрацювало. Зараз я перебуваю на Ubuntu, і це не працює. Я змінив відповідь.
GreenMatt

Не працюйте в lenovo NAS, поверніть None. Зараз я використовую імпорт друку сокета (socket.gethostname ())
Руй Мартінс

@RuiMartins: Як я вже сказав, це, здається, не працює всюди. Радий, що ти знайшов щось, що працює.
GreenMatt

5

Мені потрібно було ім'я ПК для використання в моєму файлі ConfLog PyLog, і бібліотека сокет недоступна, але бібліотека OS є.

Для 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()

І тоді ви можете використовувати ім'я, щоб знайти addr:

print(socket.gethostbyname(sock_name))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.