如何使用Python获取系统主机名?

931

我正在为本地网络编写聊天程序,希望使用Python能够识别计算机并获取用户设置的计算机名称。

12个回答

1413

使用socket及其gethostname()函数。这将获取Python解释器所在计算机的hostname

import socket
print(socket.gethostname())

108
请注意,对于FQDN,您可以使用socket.getfqdn()函数。 - Dave Forgac
23
socket.gethostname() 返回本地主机名,而 os.uname()[1] 或 platform.uname()[1] 则返回操作系统中的网络名称或节点名称。 - LetsOMG
1
这个是可移植的吗? - Charlie Parker
如何在没有DNS后缀的情况下获取主机名? - iEfimoff
1
@iEfimoff 在某些系统(如rhel 7.9 x86_64)中,socket.gethostname仍然返回带有FQDN的完整名称。我使用sysName = socket.gethostname().split(".")[0]将短主机名存储到一个名为'sysName'的变量中。 - Chris
这怎么不在顶部? - user122049

479

这两个方案都很易于移植:

import platform
platform.node()

import socket
socket.gethostname()

使用 HOSTHOSTNAME 环境变量的解决方案不具备可移植性。即使在您运行它时可以工作,但在诸如 cron 等特殊环境中运行时可能无法正常工作。


9
好的,半可移植。在某些平台上,platform.node() 返回完全限定域名,而在其他平台上仅返回主机名。 - raindog308
5
python -m timeit "import socket; socket.gethostname()"执行10000次循环,取最佳结果,每次循环耗时76.3微秒。 该命令的功能是导入socket模块,并获取主机名。 - Below the Radar
17
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop - Below the Radar
29
不用担心,我通常只在脚本中调用其中一个。 - robert
12
platform.node() 比 os.getenv 更快。gethostname甚至不是一个竞争者。但如果时间不是一个因素:import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]应该是跨平台的,并且支持环境变量(如果存在),这允许在紧急情况下进行一些用户控制,例如 HOSTNAME=correct python xyz.py - Orwellophile
显示剩余3条评论

183

你可能已经加载了os模块,因此另一个建议是:

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

14
使用“os”模块的解决方案+1。虽然不是很可移植且不是非常准确,但还是很方便的。 - MestreLion
42
os.uname在Windows上不受支持: http://docs.python.org/dev/library/os#os.uname - Noam Manos
17
在3.3及以上版本中,您还可以使用os.uname().nodename来使其更加明显。 - Hut8
4
下面的答案提供了类似的代码 platform.uname()[1],在Windows上也可以使用。 - fantabolous
11
@fantabolous,你可能不应该使用像“下面”这样的位置词,因为在降落过程中答案可能已经发生了变化。 - Jonathan Komar
显示剩余4条评论

78

那么这个怎么样:

import platform

h = platform.uname()[1]

实际上,您可能希望查看platform.uname()中的所有结果。


1
对我来说,在Ubuntu和Windows上都可以工作。谢谢! - GollyJer
1
platform.uname().nodeplatform.uname()[1]更冗长,我认为它是在与os.uname等效的版本在另一个评论中提到同时引入的。 - Luc
这应该与 platform.node() 相同。 - nurettin

65

os.getenv('HOSTNAME')os.environ['HOSTNAME'] 并不总是有效。在 cron 作业和 WSDL 中,HTTP 主机名未设置。使用以下代码替代:

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

即使在Windows上,它始终返回完全限定的主机名,即使您在/etc/hosts中定义了一个短别名。

如果您在/etc/hosts中定义了别名,则socket.gethostname()将返回该别名。platform.uname()[1]也会返回相同的内容。

我遇到了一个以上述方法无法解决的情况。这是我现在正在使用的方法:

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

它首先调用gethostname函数以查看返回的结果是否类似于主机名,如果不是,则使用我的原始解决方案。


16
您可能需要使用socket.getfqdn(),尽管它并不是OP所要求的内容。 - jfs
在我的机器上(运行着FreeBSD),socket.gethostbyaddr(socket.gethostname()) 返回 ('localhost', ['my-machine-name', 'my-machine-namelocaldomain'], ['::1']),因此只返回第一个元素 localhost。(同时,socket.gethostname() 对我来说返回 my-machine-name。) - jamesdlin

52

从至少 python >= 3.3 开始:

您可以使用字段nodename而不使用数组索引:

os.uname().nodename

虽然,甚至os.uname的文档建议使用socket.gethostname()


1
根据文档os.uname仅适用于“最近的Unix版本”。 - Pedru
@CharlesPlager 对我来说在Python 3.8.6上运行良好,RHEL7容器在OpenShift中运行。 - diman82
不可移植,不支持Windows - Orsiris de Jong

25

如果我理解正确,您正在寻找socket.gethostname函数:

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

16

你需要执行这行代码

sock_name = socket.gethostname()

然后,您可以使用名称查找地址:

print(socket.gethostbyname(sock_name))

这种方法对我来说只返回了IP - undefined

14

socket.gethostname()可以做什么?


12

要获取完全合格的主机名,请使用socket.getfqdn()。

import socket

print socket.getfqdn()

是的,但不幸的是有时它只返回“localhost”,甚至不是由socket.gethostname()返回的主机名。 - Asclepius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接