Wie kann ich Python verwenden, um den Systemhostnamen abzurufen?


679

Ich schreibe ein Chat-Programm für ein lokales Netzwerk. Ich möchte in der Lage sein, Computer zu identifizieren und den vom Benutzer festgelegten Computernamen mit Python zu erhalten.

Antworten:


1043

Verwendung socketund deren gethostname()Funktionalität. Dadurch wird hostnameder Computer abgerufen, auf dem der Python-Interpreter ausgeführt wird:

import socket
print(socket.gethostname())

70
Nun, das ist nicht richtig. Es funktioniert für mich offline und zu Hause, aber jetzt bin ich ein Büro und dies gibt einen anderen Hostnamen zurück.
DataGreed

74
Und beachten Sie, dass Sie für den FQDN verwenden könnensocket.getfqdn()
Dave Forgac

31
@DataGreed, weil sich Ihr Hostname ändert. Nicht Pythons Problem.
Strickli

4
@DataGreed 1. Ich bin mir ziemlich sicher, dass es nicht "zufällig" ist, obwohl es Ihnen so erscheinen mag. 2. Die Frage lautete "Systemhostname", nicht "Systemname". 3. Für eine große Anzahl von Systemen (zugegebenermaßen ohne Windows) sind die Host- und Systemnamen identisch.
Strickli

7
Nur neugierig, was der Unterschied zwischen socket.gethostname () und os.uname () [1] oder platform.uname () [1] ist
LetsOMG

387

Beide sind ziemlich portabel:

import platform
platform.node()

import socket
socket.gethostname()

Lösungen, die die Umgebungsvariablen HOSToder verwenden HOSTNAME, sind nicht portierbar. Selbst wenn es auf Ihrem System funktioniert, wenn Sie es ausführen, funktioniert es möglicherweise nicht, wenn es in speziellen Umgebungen wie cron ausgeführt wird.


6
Nun, halb tragbar. Auf einigen Plattformen gibt platform.node () den fqdn und auf anderen nur den Hostnamen
raindog308

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Unter dem Radar

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

7
@BelowtheRadar Keine Sorge, ich rufe normalerweise nur einmal pro Skript auf.
Robert

6
platform.node () ist noch schneller als os.getenv. gethostname ist nicht einmal ein Anwärter. Aber wenn Zeit kein Faktor ist: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]sollte plattformübergreifend sein und Umgebungsvariablen unterstützen, falls vorhanden - was eine gewisse Benutzerkontrolle unter schwierigen Umständen ermöglicht, z. B.HOSTNAME=correct python xyz.py
Orwellophile

121

Sie werden das OS-Modul wahrscheinlich trotzdem laden, daher wäre ein weiterer Vorschlag:

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

8
+1 für eine Lösung mit osModul. Nicht tragbar und nicht wirklich genau, aber trotzdem praktisch.
MestreLion

20
os.uname wird unter Windows nicht unterstützt: docs.python.org/dev/library/os#os.uname
Noam Manos

9
Sie können auch os.uname (). Nodename tun, um es in 3.3+
Hut8

4
Eine Antwort unten sieht ähnlich aus platform.uname()[1], was unter Windows funktioniert.
fantastisch

6
@fantabolous Sie sollten wahrscheinlich keine Positionswörter wie "unten" verwenden, da sich die Antworten während der Landung möglicherweise verschoben haben;)
Jonathan Komar

65

Wie wäre es mit :

import platform

h = platform.uname()[1]

Eigentlich möchten Sie vielleicht einen Blick auf das gesamte Ergebnis in werfen platform.uname()


1
Arbeitete unter Ubuntu und Windows für mich. Vielen Dank! 👍
GollyJer

61

os.getenv('HOSTNAME')und os.environ['HOSTNAME']nicht immer arbeiten. In Cron-Jobs und WSDL ist HTTP HOSTNAME nicht festgelegt. Verwenden Sie stattdessen Folgendes:

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

Es gibt immer (auch unter Windows) einen vollständig qualifizierten Hostnamen zurück, selbst wenn Sie in / etc / hosts einen kurzen Alias ​​definiert haben .

Wenn Sie einen Alias in definierten / etc / hosts dann socket.gethostname()kehrt das Alias. platform.uname()[1]macht das gleiche.

Ich bin auf einen Fall gestoßen, in dem das oben genannte nicht funktioniert hat. Das benutze ich jetzt:

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

Zuerst wird gethostname aufgerufen, um festzustellen, ob etwas zurückgegeben wird, das wie ein Hostname aussieht. Andernfalls wird meine ursprüngliche Lösung verwendet.


15
Sie wollen wahrscheinlich socket.getfqdn(), obwohl es nicht das ist, was das OP verlangt
jfs

17

Wenn ich richtig liege, suchen Sie nach der Funktion socket.gethostname:

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



5

Auf einigen Systemen wird der Hostname in der Umgebung festgelegt. Wenn dies bei Ihnen der Fall ist, kann das OS- Modul es über os.getenv aus der Umgebung ziehen . Wenn beispielsweise HOSTNAME die Umgebungsvariable ist, die das enthält, was Sie möchten, erhalten Sie Folgendes:

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

Update: Wie in den Kommentaren erwähnt, funktioniert dies nicht immer, da nicht jede Umgebung auf diese Weise eingerichtet ist. Ich glaube, dass ich zu dem Zeitpunkt, als ich dies zum ersten Mal beantwortete, diese Lösung verwendet habe, da es das erste war, was ich bei einer Websuche gefunden hatte, und es zu dieser Zeit für mich funktioniert hat. Aufgrund der mangelnden Portabilität würde ich dies jetzt wahrscheinlich nicht verwenden. Ich lasse diese Antwort jedoch zu Referenzzwecken. FWIW macht andere Importe überflüssig, wenn Ihre Umgebung den Systemnamen hat und Sie das Betriebssystemmodul bereits importieren. Testen Sie es - wenn es nicht in allen Umgebungen funktioniert, in denen Ihr Programm ausgeführt werden soll, verwenden Sie eine der anderen bereitgestellten Lösungen.


5
Das gibt für mich "Keine" zurück. Laut dem von Ihnen geposteten Link bedeutet dies, dass die Variable 'HOSTNAME' nicht existiert ...: - /
John

@ John: Bist du unter Windows? Es hat bei mir auf einer Linux-Box funktioniert, aber ich bekomme auch unter Windows keine.
GreenMatt

@ MuhiaNJoroge: Ich denke, das hängt von Ihrer Implementierung / Installation ab. Als ich diese Antwort schrieb, war ich auf einer Red Hat Box und es hat funktioniert. Jetzt bin ich auf Ubuntu und es funktioniert nicht. Ich habe die Antwort geändert.
GreenMatt

Funktioniert nicht in Lenovo NAS, gibt keine zurück. Jetzt verwende ich Import Socket Print (socket.gethostname ())
Rui Martins

@ RuiMartins: Wie gesagt, es scheint nicht überall zu funktionieren. Ich bin froh, dass du etwas gefunden hast, das funktioniert.
GreenMatt

5

Ich brauchte den Namen des PCs, um ihn in meiner PyLog-Konfigurationsdatei zu verwenden, und die Socket-Bibliothek ist nicht verfügbar, die OS-Bibliothek jedoch.

Für Windows habe ich verwendet:

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

Dabei ist defaultValue eine Zeichenfolge, um zu verhindern, dass None zurückgegeben wird


12
COMPUTERNAME ist eine reine Microsoft-Umgebungsvariable und daher nicht portierbar.
Dwight Spencer

1
Ja, aber es funktioniert für MS-Systeme, und wenn es passt, funktioniert es. Oft sind die Leute hier zu sehr mit Geschwindigkeit oder Plattformunabhängigkeit verbunden, wenn Praktikabilität und die Frage sie irrelevant machen.
Bill Kidd

7
@BillKidd OP erwähnt Windows, OS X und Linux in der Frage, daher ist die Notwendigkeit der Systemportabilität eine sehr vernünftige Annahme.
Zstewart

1
@BillKidd Während es im Allgemeinen richtig ist, dass Sie vorzeitige Optimierung oder Portabilität vermeiden sollten, geht die Verwendung einer leicht verfügbaren und wahrscheinlich wartbareren Lösung, da sie portabler ist, in das entgegengesetzte Extrem.
Mad Physicist

2

Sie müssen diese Codezeile ausführen

sock_name = socket.gethostname()

Und dann können Sie den Namen verwenden, um die Adresse zu finden:

print(socket.gethostbyname(sock_name))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.