Comment puis-je utiliser Python pour obtenir le nom d'hôte du système?

681

J'écris un programme de chat pour un réseau local. J'aimerais pouvoir identifier les ordinateurs et obtenir le nom d'ordinateur défini par l'utilisateur avec Python.

John
la source

Réponses:

1043

Utilisation socketet ses gethostname()fonctionnalités. Cela obtiendra l' hostnameordinateur sur lequel s'exécute l'interpréteur Python:

import socket
print(socket.gethostname())
Alex
la source
70
eh bien, ce n'est pas correct. Cela fonctionne pour moi hors ligne et à la maison, mais maintenant je suis un bureau et cela renvoie un nom d'hôte différent.
DataGreed
74
Et notez que pour le FQDN, vous pouvez utilisersocket.getfqdn()
Dave Forgac
31
@DataGreed c'est parce que votre nom d'hôte change. Pas le problème de python.
strickli
4
@DataGreed 1. Je suis assez certain que ce n'est pas "aléatoire", même si cela peut vous sembler ainsi. 2. La question disait "nom d'hôte du système", pas "nom du système". 3. Pour un grand nombre de systèmes (sans compter les fenêtres), les noms d'hôte et de système sont identiques.
strickli
8
Juste curieux de savoir quelle est la différence entre socket.gethostname () et os.uname () [1] ou platform.uname () [1]
LetsOMG
388

Les deux sont assez portables:

import platform
platform.node()

import socket
socket.gethostname()

Les solutions utilisant les variables d'environnement HOSTou HOSTNAMEne sont pas portables. Même s'il fonctionne sur votre système lorsque vous l'exécutez, il peut ne pas fonctionner lorsqu'il est exécuté dans des environnements spéciaux tels que cron.

robert
la source
6
Eh bien, semi-portable. Sur certaines plates-formes, platform.node () donne le fqdn et sur d'autres, seul le nom d'hôte
raindog308
3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Sous le radar
8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
Sous le radar
7
@BelowtheRadar ne vous inquiétez pas, je n'appelle généralement ces deux fois qu'une fois par script.
robert
6
platform.node () est encore plus rapide que os.getenv. gethostname n'est même pas un concurrent. Mais si le temps n'est pas un facteur: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]devrait être multiplateforme et prendre en charge les variables d'environnement si elles existent - ce qui permet un certain contrôle de l'utilisateur dans des situations d'urgence, par exempleHOSTNAME=correct python xyz.py
Orwellophile
121

Vous allez probablement charger le module os de toute façon, donc une autre suggestion serait:

import os
myhost = os.uname()[1]
mike0042
la source
8
+1 pour une solution utilisant le osmodule. Pas portable et pas vraiment précis, mais pratique quand même.
MestreLion
20
os.uname n'est pas pris en charge sous Windows: docs.python.org/dev/library/os#os.uname
Noam Manos
9
Vous pouvez également faire os.uname (). Nodename pour le rendre un peu plus évident dans 3.3+
Hut8
4
Une réponse ci-dessous donne l'aspect similaire platform.uname()[1], qui fonctionne sur Windows.
2015
6
@fantabolous Vous ne devriez probablement pas utiliser de mots positionnels comme "ci-dessous" car les réponses peuvent avoir changé pendant l'atterrissage;)
Jonathan Komar
65

Qu'en est-il de :

import platform

h = platform.uname()[1]

En fait, vous voudrez peut-être jeter un œil à tous les résultats platform.uname()

Lucien Hercaud
la source
1
A travaillé sur Ubuntu et Windows pour moi. Merci! 👍
GollyJer
61

os.getenv('HOSTNAME')et os.environ['HOSTNAME']ne fonctionnent pas toujours. Dans les tâches cron et WSDL, HTTP HOSTNAME n'est pas défini. Utilisez-le à la place:

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

Il retourne toujours (même sous Windows) un nom d'hôte complet, même si vous avez défini un court alias dans / etc / hosts .

Si vous avez défini un alias dans / etc / hosts, puis socket.gethostname()retournera l'alias. platform.uname()[1]fait la même chose.

J'ai rencontré un cas où ce qui précède n'a pas fonctionné. Voici ce que j'utilise maintenant:

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

Il appelle d'abord gethostname pour voir s'il renvoie quelque chose qui ressemble à un nom d'hôte, sinon il utilise ma solution d'origine.

Tom Ekberg
la source
15
vous voulez probablement socket.getfqdn(), mais ce n'est pas ce que l'OP demande
jfs
17

Si j'ai raison, vous recherchez la fonction socket.gethostname:

>> import socket
>> socket.gethostname()
'terminus'
terminus
la source
13

Depuis au moins python> = 3.3 :

Vous pouvez utiliser le champ nodenameet éviter d'utiliser l'indexation de tableaux:

os.uname().nodename

Même si la documentation d' os.uname suggère d'utilisersocket.gethostname()

Shubham Chaudhary
la source
11

socket.gethostname() pourrait faire

vpit3833
la source
5

Sur certains systèmes, le nom d'hôte est défini dans l'environnement. Si tel est le cas pour vous, le module os peut le retirer de l'environnement via os.getenv . Par exemple, si HOSTNAME est la variable d'environnement contenant ce que vous voulez, les éléments suivants l'obtiendront:

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

Mise à jour: Comme indiqué dans les commentaires, cela ne fonctionne pas toujours, car l'environnement de tout le monde n'est pas configuré de cette façon. Je crois qu'au moment où j'ai répondu au départ, j'utilisais cette solution car c'était la première chose que j'avais trouvée dans une recherche sur le Web et cela a fonctionné pour moi à l'époque. En raison du manque de portabilité, je ne l'utiliserais probablement pas maintenant. Cependant, je laisse cette réponse à des fins de référence. FWIW, cela élimine le besoin d'autres importations si votre environnement a le nom du système et que vous importez déjà le module os. Testez-le - s'il ne fonctionne pas dans tous les environnements dans lesquels vous prévoyez que votre programme fonctionnera, utilisez l'une des autres solutions fournies.

GreenMatt
la source
5
Cela me renvoie "Aucun". Selon le lien que vous avez publié, cela signifie que la variable 'HOSTNAME' n'existe pas ...: - /
John
@John: Êtes-vous sous Windows? Cela a fonctionné pour moi sur une boîte Linux, mais je reçois également None sur Windows.
GreenMatt
@MuhiaNJoroge: Je pense que cela dépend de votre implémentation / installation. Quand j'ai écrit cette réponse, j'étais sur une boîte Red Hat et cela a fonctionné. Maintenant, je suis sur Ubuntu et cela ne fonctionne pas. J'ai modifié la réponse.
GreenMatt
Ne fonctionne pas sur le lenovo NAS, retourne Aucun. Maintenant, j'utilise l'import de socket print (socket.gethostname ())
Rui Martins
@RuiMartins: Comme je l'ai dit, cela ne semble pas fonctionner partout. Heureux que vous ayez trouvé quelque chose qui fonctionne.
GreenMatt
5

J'avais besoin du nom du PC à utiliser dans mon fichier de configuration PyLog, et la bibliothèque de sockets n'est pas disponible, mais la bibliothèque os l'est.

Pour Windows, j'ai utilisé:

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

Où defaultValue est une chaîne pour empêcher Aucun d'être renvoyé

Bill Kidd
la source
12
COMPUTERNAME est une variable d'environnement très Microsoft uniquement et n'est donc pas portable.
Dwight Spencer
1
Oui, mais cela fonctionne pour les systèmes MS, et si cela convient, cela fonctionne. Souvent, les gens ici sont trop liés à la vitesse ou à l'indépendance de la plate-forme lorsque la praticité et la question les rendent hors de propos.
Bill Kidd
7
@BillKidd OP mentionne Windows, OS X et Linux dans la question, donc avoir besoin de la portabilité du système est une hypothèse très raisonnable.
zstewart
1
@BillKidd Bien qu'en général, il est vrai que vous devez éviter une optimisation ou une portabilité prématurée, ne pas utiliser une solution facilement disponible et sans doute plus maintenable car elle est plus portable va à l'extrême opposé.
Mad Physicist
2

Vous devez exécuter cette ligne de code

sock_name = socket.gethostname()

Et puis vous pouvez utiliser le nom pour trouver l'adr:

print(socket.gethostbyname(sock_name))
Parzifal Kali
la source