Como posso usar o Python para obter o nome do host do sistema?

680

Estou escrevendo um programa de bate-papo para uma rede local. Gostaria de poder identificar computadores e obter o nome do computador definido pelo usuário com Python.

John
fonte

Respostas:

1043

Use sockete sua gethostname()funcionalidade. Isso obterá o hostnamecomputador em que o interpretador Python está sendo executado:

import socket
print(socket.gethostname())
Alex
fonte
70
bem, isso não está correto. Funciona para mim offline e em casa, mas agora sou um escritório e isso retorna um nome de host diferente.
DataGreed
74
E observe que, para o FQDN, você pode usarsocket.getfqdn()
Dave Forgac
31
@DataGreed é porque seu nome de host está mudando. Não é problema do python.
Strickli
4
@DataGreed 1. Estou bastante certo de que não é "aleatório", embora possa parecer assim para você. 2. A pergunta dizia "nome do host do sistema", não "nome do sistema". 3. Para um grande número de sistemas (reconhecidamente não incluindo janelas), os nomes de host e sistema são os mesmos.
strickli
7
Apenas curioso, qual é a diferença entre socket.gethostname () e os.uname () [1] ou platform.uname () [1]
LetsOMG
388

Ambos são bastante portáteis:

import platform
platform.node()

import socket
socket.gethostname()

Quaisquer soluções usando as variáveis ​​de ambiente HOSTou HOSTNAMEnão são portáteis. Mesmo que funcione no seu sistema quando você o executa, pode não funcionar quando executado em ambientes especiais, como cron.

Robert
fonte
6
Bem, semi-portátil. Em algumas plataformas, platform.node () dá o fqdn e em outros, apenas o nome do host
raindog308
3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
Abaixo do radar
8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
Abaixo do radar
7
@ BelowtheRadar não se preocupe, eu normalmente chamo apenas um deles uma vez por script.
22680 Robert
6
platform.node () é ainda mais rápido que os.getenv. gethostname nem é um candidato. Mas se o tempo não é um fator: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]deve ser variáveis multi-plataforma e ambiente de suporte, se eles existem - o que permite algum controle de usuário em circunstâncias que exijam, por exemploHOSTNAME=correct python xyz.py
Orwellophile
121

Você provavelmente carregará o módulo OS de qualquer maneira, então outra sugestão seria:

import os
myhost = os.uname()[1]
mike0042
fonte
8
+1 para uma solução usando o osmódulo. Não é portátil e não é realmente preciso, mas é útil de qualquer maneira.
MestreLion
20
o os.uname não é suportado no Windows: docs.python.org/dev/library/os#os.uname
Noam Manos
9
Você também pode fazer os.uname () nodename para torná-lo um pouco mais óbvio em 3.3+.
Hut8
4
Uma resposta abaixo fornece uma aparência semelhante platform.uname()[1], que funciona no Windows.
fantabolous
6
@fantabolous Você provavelmente não deve usar palavras posicionais como "abaixo" como respostas pode ter deslocado durante o pouso;)
Jonathan Komar
65

A respeito :

import platform

h = platform.uname()[1]

Na verdade, você pode querer ver todos os resultados em platform.uname()

Lucien Hercaud
fonte
1
Trabalhou no Ubuntu e Windows para mim. Obrigado! Gol
GollyJer
61

os.getenv('HOSTNAME')e os.environ['HOSTNAME']nem sempre funciona. Em tarefas cron e WSDL, HTTP HOSTNAME não está definido. Use isto:

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

Sempre (mesmo no Windows) retorna um nome completo de host, mesmo se você definiu um alias curto em / etc / hosts .

Se você definiu um alias no / etc / hosts , socket.gethostname()retornará o alias. platform.uname()[1]faz a mesma coisa.

Corri para um caso em que o acima não funcionou. Isto é o que estou usando agora:

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

Primeiro chama gethostname para ver se retorna algo que se parece com um nome de host; caso contrário, ele usa minha solução original.

Tom Ekberg
fonte
15
você provavelmente vai querer socket.getfqdn(), no entanto, não é o que o OP pede
jfs
17

Se eu estiver correto, você está procurando a função socket.gethostname:

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

De pelo menos python> = 3.3 :

Você pode usar o campo nodenamee evitar o uso de indexação de matriz:

os.uname().nodename

Embora até a documentação do os.uname sugira o uso desocket.gethostname()

Shubham Chaudhary
fonte
11

socket.gethostname() poderia fazer

vpit3833
fonte
5

Em alguns sistemas, o nome do host é definido no ambiente. Se esse é o seu caso, o módulo os pode retirá-lo do ambiente via os.getenv . Por exemplo, se HOSTNAME é a variável de ambiente que contém o que você deseja, o seguinte será obtido:

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

Atualização: conforme observado nos comentários, isso nem sempre funciona, pois nem todo mundo é configurado dessa maneira. Acredito que, no momento em que respondi inicialmente, estava usando esta solução, pois era a primeira coisa que encontrei em uma pesquisa na web e funcionou para mim na época. Devido à falta de portabilidade, eu provavelmente não usaria isso agora. No entanto, estou deixando esta resposta para fins de referência. FWIW, elimina a necessidade de outras importações se o seu ambiente tiver o nome do sistema e você já estiver importando o módulo os. Teste - se não funcionar em todos os ambientes em que você espera que seu programa funcione, use uma das outras soluções fornecidas.

GreenMatt
fonte
5
Isso retorna "Nenhum" para mim. De acordo com o link que você postou, isso significa que a variável 'HOSTNAME' não existe ...: - /
John
@ John: Você está no Windows? Funcionou para mim em uma caixa Linux, mas também recebo Nenhum no Windows.
GreenMatt
@MuhiaNJoroge: Eu acho que isso depende da sua implementação / instalação. Quando escrevi essa resposta, estava em uma caixa da Red Hat e funcionou. Agora estou no Ubuntu e não funciona. Eu modifiquei a resposta.
GreenMatt
Não funciona no lenovo NAS, retorna Nenhum. Agora estou usando a importação de soquete de impressão (socket.gethostname ())
Rui Martins
@RuiMartins: Como eu disse, parece que não funciona em todos os lugares. Que bom que você encontrou algo que funciona.
GreenMatt
5

Eu precisava do nome do PC para usar no meu arquivo conf PyLog, e a biblioteca de soquetes não está disponível, mas a biblioteca os está.

Para Windows , usei:

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

Onde defaultValue é uma sequência para impedir que nenhum seja retornado

Bill Kidd
fonte
12
COMPUTERNAME é uma variável de ambiente exclusiva da Microsoft e, portanto, não é portátil.
Dwight Spencer
1
Sim, mas funciona para sistemas MS e, se for adequado, funciona. Muitas vezes as pessoas aqui se envolvem demais na velocidade ou na independência da plataforma quando a praticidade e a questão as tornam irrelevantes.
Bill Kidd
7
O @BillKidd OP menciona Windows, OS X e Linux na questão, portanto, a necessidade de portabilidade do sistema é uma suposição bastante razoável.
zstewart
1
@BillKidd Embora, em geral, seja verdade que você deve evitar otimização ou portabilidade prematuras, não usar uma solução prontamente disponível e sem dúvida mais sustentável, porque é mais portátil, está indo para o extremo oposto.
Mad físico
2

Você precisa executar esta linha de código

sock_name = socket.gethostname()

E então você pode usar o nome para encontrar o endereço:

print(socket.gethostbyname(sock_name))
Parzifal Kali
fonte