Jak mogę użyć Pythona, aby uzyskać systemową nazwę hosta?

681

Piszę program do czatu dla sieci lokalnej. Chciałbym móc zidentyfikować komputery i uzyskać nazwę komputera ustawioną przez użytkownika w Pythonie.

Jan
źródło

Odpowiedzi:

1043

Zastosowanie socketi jego gethostname()funkcjonalność. Otrzyma hostnamekomputer, na którym działa interpreter Pythona:

import socket
print(socket.gethostname())
Alex
źródło
70
to nie jest poprawne. Działa dla mnie offline i w domu, ale teraz jestem biurem, a to zwraca inną nazwę hosta.
DataGreed
74
I zauważ, że do FQDN możesz użyćsocket.getfqdn()
Dave Forgac
31
@DataGreed, ponieważ zmienia się nazwa hosta. Nie problem Pythona.
strickli
4
@DataGreed 1. Jestem całkiem pewien, że to nie jest „losowe”, chociaż może ci się tak wydawać. 2. Pytanie brzmiało: „nazwa hosta systemu”, a nie „nazwa systemu”. 3. W przypadku dużej liczby systemów (co prawda nie obejmuje okien) nazwy hosta i systemu są takie same.
strickli
8
Ciekawe, jaka jest różnica między socket.gethostname () i os.uname () [1] lub platform.uname () [1]
LetsOMG
388

Oba są dość przenośne:

import platform
platform.node()

import socket
socket.gethostname()

Wszelkie rozwiązania wykorzystujące zmienne środowiskowe HOSTlub HOSTNAMEnie są przenośne. Nawet jeśli działa w systemie po uruchomieniu, może nie działać w specjalnych środowiskach, takich jak cron.

Robert
źródło
6
Cóż, częściowo przenośny. Na niektórych platformach platforma.node () podaje fqdn, a na innych tylko nazwę hosta
raindog308,
3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Poniżej radaru
8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
Poniżej radaru
7
@Poniżej Radar, nie martw się, zwykle wywołuję tylko jeden raz na skrypt.
Robert
6
Platform.node () jest nawet szybszy niż os.getenv. gethostname nie jest nawet konkurentem. Ale jeśli czas nie jest czynnikiem: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]powinno być cross-platform i środowisku obsługują zmiennych jeśli istnieją - co pozwala na pewną kontrolę użytkownika w okolicznościach wymagających natychmiastowego przykładHOSTNAME=correct python xyz.py
Orwellophile
121

Prawdopodobnie i tak załadujesz moduł OS, więc inną sugestią byłoby:

import os
myhost = os.uname()[1]
mike0042
źródło
8
+1 za rozwiązanie wykorzystujące osmoduł. Nie przenośny i niezbyt dokładny, ale i tak przydatny.
MestreLion
20
os.uname nie jest obsługiwany w systemie Windows: docs.python.org/dev/library/os#os.uname
Noam Manos
9
Możesz również wykonać os.uname (). Nodename, aby było to bardziej oczywiste w 3.3+
Hut8
4
Odpowiedź poniżej daje podobny wygląd platform.uname()[1], który DZIAŁA w systemie Windows.
fantastyczny
6
@fantabolous Prawdopodobnie nie powinieneś używać słów pozycyjnych, takich jak „poniżej”, ponieważ odpowiedzi mogły ulec zmianie podczas lądowania;)
Jonathan Komar
65

Co powiesz na :

import platform

h = platform.uname()[1]

Właściwie możesz rzucić okiem na cały wynik platform.uname()

Lucien Hercaud
źródło
1
Pracowałem dla Ubuntu i Windows dla mnie. Dzięki! 👍
GollyJer
61

os.getenv('HOSTNAME')i os.environ['HOSTNAME']nie zawsze działają. W zadaniach cron i WSDL nazwa HTTP HOSTNAME nie jest ustawiona. Zamiast tego użyj tego:

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

Zawsze (nawet w systemie Windows) zwraca w pełni kwalifikowaną nazwę hosta, nawet jeśli zdefiniowałeś krótki alias w / etc / hosts .

Jeśli zdefiniowany alias w pliku / etc / hosts następnie socket.gethostname()powróci alias. platform.uname()[1]robi to samo.

Natknąłem się na przypadek, w którym powyższe nie zadziałało. Z tego teraz korzystam:

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

Najpierw wywołuje gethostname, aby sprawdzić, czy zwraca coś, co wygląda jak nazwa hosta, jeśli nie, używa mojego oryginalnego rozwiązania.

Tom Ekberg
źródło
15
prawdopodobnie chcesz socket.getfqdn(), ale nie o to prosi OP
jfs
17

Jeśli mam rację, szukasz funkcji socket.gethostname:

>> import socket
>> socket.gethostname()
'terminus'
stacja końcowa
źródło
13

Z przynajmniej python> = 3.3 :

Możesz użyć tego pola nodenamei uniknąć indeksowania tablic:

os.uname().nodename

Chociaż nawet dokumentacja os.uname sugeruje użyciesocket.gethostname()

Shubham Chaudhary
źródło
11

socket.gethostname() mógłby zrobić

vpit3833
źródło
5

W niektórych systemach nazwa hosta jest ustawiana w środowisku. Jeśli tak jest w twoim przypadku, moduł os może wyciągnąć go ze środowiska przez os.getenv . Na przykład, jeśli NAZWA_HOSTA jest zmienną środowiskową zawierającą to, czego chcesz, następujące:

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

Aktualizacja: Jak zauważono w komentarzach, nie zawsze to działa, ponieważ nie wszyscy są skonfigurowani w ten sposób. Wierzę, że w chwili, gdy początkowo na to odpowiadałem, korzystałem z tego rozwiązania, ponieważ była to pierwsza rzecz, którą znalazłem podczas wyszukiwania w sieci i wtedy działało to dla mnie. Z powodu braku przenośności prawdopodobnie nie użyłbym tego teraz. Pozostawiam jednak tę odpowiedź w celach informacyjnych. FWIW, eliminuje potrzebę innych importów, jeśli twoje środowisko ma nazwę systemu i już importujesz moduł os. Przetestuj - jeśli nie działa we wszystkich środowiskach, w których oczekuje się działania programu, skorzystaj z jednego z pozostałych dostarczonych rozwiązań.

GreenMatt
źródło
5
To zwraca „Brak” dla mnie. Zgodnie z opublikowanym linkiem oznacza to, że zmienna „HOSTNAME” nie istnieje ...: - /
John
@John: Czy korzystasz z systemu Windows? Działa to dla mnie na Linuksie, ale dostaję Brak także na Windowsie.
GreenMatt,
@MuhiaNJoroge: Myślę, że to zależy od twojej implementacji / instalacji. Kiedy napisałem tę odpowiedź, byłem na pudełku Red Hat i zadziałało. Teraz jestem na Ubuntu i to nie działa. Zmodyfikowałem odpowiedź.
GreenMatt
Nie działa w Lenovo NAS, zwróć Brak. Teraz używam importu wydruku gniazda (socket.gethostname ())
Rui Martins,
@RuiMartins: Jak powiedziałem, nie wszędzie to działa. Cieszę się, że znalazłeś coś, co działa.
GreenMatt,
5

Potrzebowałem nazwy komputera, aby użyć jej w moim pliku conf PyLog, a biblioteka gniazd nie jest dostępna, ale biblioteka OS jest.

Do systemu Windows użyłem:

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

Gdzie defaultValue to ciąg znaków, który zapobiega zwróceniu wartości None

Bill Kidd
źródło
12
COMPUTERNAME jest zmienną środowiskową tylko dla Microsoft i dlatego nie jest przenośna.
Dwight Spencer
1
Tak, ale działa dla systemów MS, a jeśli pasuje, działa. Wiele razy ludzie tutaj są zbyt mocno uwikłani w szybkość lub niezależność od platformy, gdy praktyczność i pytanie sprawiają, że nie mają one znaczenia.
Bill Kidd
7
@BillKidd OP wspomina w tym pytaniu o systemach Windows, OS X i Linux, więc potrzeba przenośności systemu jest bardzo rozsądnym założeniem.
zstewart,
1
@BillKidd Chociaż ogólnie prawdą jest, że należy unikać przedwczesnej optymalizacji lub przenośności, nieużywanie łatwo dostępnego i prawdopodobnie łatwiejszego w utrzymaniu rozwiązania, ponieważ jest ono bardziej przenośne, zmierza w przeciwnym kierunku.
Szalony fizyk
2

Musisz wykonać ten wiersz kodu

sock_name = socket.gethostname()

A potem możesz użyć nazwy, aby znaleźć adresata:

print(socket.gethostbyname(sock_name))
Parzifal Kali
źródło