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.

Odpowiedzi:


1043

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

import socket
print(socket.gethostname())

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.


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]

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()


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.


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'



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ń.


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


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))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.