Come posso usare Python per ottenere il nome host del sistema?


681

Sto scrivendo un programma di chat per una rete locale. Vorrei essere in grado di identificare i computer e ottenere il nome del computer impostato dall'utente con Python.

Risposte:


1043

Uso sockete sua gethostname()funzionalità. Questo otterrà il hostnamecomputer su cui è in esecuzione l'interprete Python:

import socket
print(socket.gethostname())

70
bene, non è corretto. Funziona per me offline e in casa, ma ora sono un ufficio e questo restituisce un nome host diverso.
Data accordo

74
E nota che per l'FQDN puoi usaresocket.getfqdn()
Dave Forgac, il

31
@DataGreed è perché il tuo nome host sta cambiando. Non è un problema di Python.
strickli,

4
@DataGreed 1. Sono abbastanza certo che non sia "casuale", anche se può sembrare così. 2. La domanda diceva "nome host di sistema", non "nome sistema". 3. Per un gran numero di sistemi (è vero che non includono le finestre) i nomi host e di sistema sono gli stessi.
Strickli,

8
Solo curioso qual è la differenza tra socket.gethostname () e os.uname () [1] o platform.uname () [1]
LetsOMG

388

Entrambi sono abbastanza portatili:

import platform
platform.node()

import socket
socket.gethostname()

Qualsiasi soluzione che utilizza le variabili di ambiente HOSTo HOSTNAMEnon è portatile. Anche se funziona sul tuo sistema quando lo esegui, potrebbe non funzionare quando eseguito in ambienti speciali come cron.


6
Bene, semi-portatile. Su alcune piattaforme, platform.node () fornisce fqdn e su altri solo il nome host
raindog308

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Sotto il radar,

8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
Sotto il radar,

7
@BelowtheRadar non ti preoccupare, di solito chiamo uno di questi solo una volta per script.
Robert

6
platform.node () è persino più veloce di os.getenv. gethostname non è nemmeno un contendente. Ma se il tempo non è un fattore: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]dovrebbe essere multipiattaforma e supportare le variabili di ambiente se esistono - il che consente un certo controllo dell'utente in circostanze urgenti, ad esempioHOSTNAME=correct python xyz.py
Orwellophile

121

Probabilmente caricherai comunque il modulo os, quindi un altro suggerimento sarebbe:

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

8
+1 per una soluzione che utilizza il osmodulo. Non portatile e non molto preciso, ma comunque utile.
MestreLion,

20
os.uname non è supportato su Windows: docs.python.org/dev/library/os#os.uname
Noam Manos

9
Puoi anche fare os.uname (). Nodename per renderlo un po 'più ovvio in 3.3+
Hut8

4
Una risposta di seguito fornisce l'aspetto simile platform.uname()[1], che FUNZIONA su Windows.
fantabolous,

6
@fantabolous Probabilmente non dovresti usare parole posizionali come "sotto" poiché le risposte potrebbero essersi spostate durante l'atterraggio;)
Jonathan Komar

65

Che dire :

import platform

h = platform.uname()[1]

In realtà potresti voler dare un'occhiata a tutti i risultati platform.uname()


1
Ho lavorato su Ubuntu e Windows per me. Grazie! 👍
GollyJer,

61

os.getenv('HOSTNAME') e os.environ['HOSTNAME'] non sempre funziona. Nei lavori cron e WSDL, HTTP HOSTNAME non è impostato. Usa questo invece:

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

Restituisce sempre (anche su Windows) un nome host completo, anche se è stato definito un breve alias in / etc / hosts .

Se hai definito un alias in / etc / hosts allorasocket.gethostname() tornerà l'alias. platform.uname()[1]fa la stessa cosa.

Mi sono imbattuto in un caso in cui quanto sopra non ha funzionato. Questo è quello che sto usando ora:

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

Per prima cosa chiama gethostname per vedere se restituisce qualcosa che assomiglia a un nome host, in caso contrario utilizza la mia soluzione originale.


15
probabilmente vorrai socket.getfqdn(), anche se non è quello che chiede l'OP
jfs

17

Se ho ragione, stai cercando la funzione socket.gethostname:

>> import socket
>> socket.gethostname()
'terminus'

13

Da almeno Python> = 3.3 :

È possibile utilizzare il campo nodenameed evitare di utilizzare l'indicizzazione dell'array:

os.uname().nodename

Sebbene, anche la documentazione di os.uname suggerisce di usaresocket.gethostname()



5

Su alcuni sistemi, il nome host è impostato nell'ambiente. In tal caso, il modulo os può estrarlo dall'ambiente tramite os.getenv . Ad esempio, se HOSTNAME è la variabile di ambiente che contiene ciò che si desidera, verrà visualizzato quanto segue:

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

Aggiornamento: come notato nei commenti, questo non funziona sempre, poiché l'ambiente di tutti non è impostato in questo modo. Credo che al momento in cui ho risposto inizialmente stavo usando questa soluzione poiché era la prima cosa che avevo trovato in una ricerca sul web e funzionava per me in quel momento. A causa della mancanza di portabilità, probabilmente non lo userei ora. Tuttavia, lascio questa risposta a scopo di riferimento. FWIW, elimina la necessità di altre importazioni se il tuo ambiente ha il nome di sistema e stai già importando il modulo os. Provalo - se non funziona in tutti gli ambienti in cui prevedi che il tuo programma funzioni, usa una delle altre soluzioni fornite.


5
Ciò restituisce "Nessuno" per me. Secondo il link che hai pubblicato, ciò significa che la variabile "HOSTNAME" non esiste ...: - /
John

@John: sei su Windows? Ha funzionato per me su un box Linux, ma ottengo None anche su Windows.
GreenMatt,

@MuhiaNJoroge: penso che dipenda dalla tua implementazione / installazione. Quando ho scritto quella risposta ero su una scatola di Red Hat e ha funzionato. Ora sono su Ubuntu e non funziona. Ho modificato la risposta.
GreenMatt

Non funziona nel NAS Lenovo, restituisce None. Ora sto usando import socket print (socket.gethostname ())
Rui Martins

@RuiMartins: come ho già detto, non sembra funzionare ovunque. Sono contento che tu abbia trovato qualcosa che funziona.
GreenMatt,

5

Avevo bisogno del nome del PC da usare nel mio file conf PyLog e la libreria socket non è disponibile, ma la libreria os lo è.

Per Windows ho usato:

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

Dove defaultValue è una stringa per impedire la restituzione di None


12
COMPUTERNAME è una variabile di ambiente solo Microsoft e quindi non portatile.
Dwight Spencer,

1
Sì, ma funziona per i sistemi MS e, se si adatta, funziona. Molte volte le persone qui si intrecciano troppo alla velocità o all'indipendenza della piattaforma quando la praticità e la domanda le rendono irrilevanti.
Bill Kidd,

7
@BillKidd OP menziona Windows, OS X e Linux nella domanda, quindi la necessità di portabilità del sistema è un presupposto molto ragionevole.
zstewart,

1
@BillKidd Mentre in generale è vero che dovresti evitare l'ottimizzazione prematura o la portabilità, non usando una soluzione prontamente disponibile e, probabilmente, più mantenibile perché più portatile sta andando all'estremo opposto.
Fisico pazzo,

2

Devi eseguire questa riga di codice

sock_name = socket.gethostname()

E poi puoi usare il nome per trovare l'add:

print(socket.gethostbyname(sock_name))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.