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


676

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

Answers:


1041

使用socket及其gethostname()功能。这将获得hostname运行Python解释器的计算机的名称:

import socket
print(socket.gethostname())

70
好吧,那是不正确的。它可以离线和在家中使用,但现在我是办公室,它将返回不同的主机名。
DataGreed 2012年

74
请注意,对于FQDN,您可以使用socket.getfqdn()
Dave Forgac 2013年

31
@DataGreed这是因为您的主机名正在更改。不是python的问题。
strickli 2013年

4
@DataGreed 1.我可以肯定它不是“随机”的,尽管它可能以这种方式出现。2.问题说的是“系统主机名”,而不是“系统名”。3.对于大量系统(不可包括Windows),主机名和系统名是相同的。
strickli 2014年

7
只是想知道socket.gethostname()和os.uname()[1]或platform.uname()[1]之间有什么区别
LetsOMG

386

这两个都是可移植的:

import platform
platform.node()

import socket
socket.gethostname()

使用HOSTHOSTNAME环境变量的任何解决方案都是不可移植的。即使它在您的系统上运行时也可以运行,但是在cron等特殊环境中运行时也可能无法运行。


6
好吧,半便携式。在某些平台上,platform.node()提供fqdn,在其他平台上,仅提供主机名
raindog308 2014年

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
低于雷达

8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
低于雷达

7
@BelowtheRadar不用担心,我通常每个脚本只调用一次。
罗伯特

6
platform.node()甚至比os.getenv还要快。gethostname甚至都不是竞争者。但是,如果时间不是一个因素:import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]应该是跨平台的并且支持环境变量(如果存在的话)-允许在紧急情况下进行某些用户控制,例如HOSTNAME=correct python xyz.py
Orwellophile

121

无论如何,您可能都将加载os模块,因此另一个建议是:

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

8
+1为使用os模块的解决方案。它不是便携式的,也不是很准确,但还是很方便。
MestreLion

20
在Windows上不支持os.uname
Noam Manos

9
你也可以做os.uname()节点名,使其多一点在3.3+明显。
Hut8

4
下面的答案给出了类似的外观platform.uname()[1],它在Windows上也可以使用。
惊人的2015年

6
@fantabolous您可能不应该使用诸如“以下”之类的位置词,因为着陆期间答案可能已经改变了;)
Jonathan Komar 2016年


61

os.getenv('HOSTNAME')而且os.environ['HOSTNAME']不总是工作。在cron作业和WSDL中,未设置HTTP HOSTNAME。使用此代替:

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

即使您在/ etc / hosts中定义了短别名,它也始终(即使在Windows上)返回标准主机名。

如果你定义的别名/ 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来查看它是否返回类似于主机名的内容,如果不是,则使用我原来的解决方案。


14
您可能想要socket.getfqdn(),尽管这不是OP所要求的
-jfs

17

如果我是正确的,那么您正在寻找socket.gethostname函数:

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



5

在某些系统上,主机名是在环境中设置的。如果是这种情况,则os模块可以通过os.getenv将其拉出环境。例如,如果HOSTNAME是包含所需内容的环境变量,则将通过以下方式获取它:

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

更新:如评论中所述,这并不总是可行,因为并非每个人的环境都是以此方式设置的。我相信,当我最初回答这个问题时,我正在使用此解决方案,因为这是我在网络搜索中发现的第一件事,当时对我有用。由于缺乏可移植性,我现在可能不会使用它。但是,我将这个答案留作参考。FWIW,如果您的环境具有系统名称并且您已经导入了os模块,那么它确实消除了其他导入的需要。测试它-如果它不能在您希望程序在其中运行的所有环境中都起作用,请使用提供的其他解决方案之一。


5
为我返回“无”。根据您发布的链接,这意味着变量“ HOSTNAME”不存在...:-/
John

@John:您在Windows上吗?它在Linux机器上对我有用,但在Windows上也没有。
GreenMatt

@MuhiaNJoroge:我认为这取决于您的实现/安装。当我写那个答案时,我在一个Red Hat盒子上,它起作用了。现在我在Ubuntu上,它不起作用。我已经修改了答案。
GreenMatt 2014年

在lenovo NAS中不起作用,返回None。现在,我正在使用导入套接字打印(socket.gethostname())
Rui Martins 2015年

@RuiMartins:正如我所说,它似乎并非在所有地方都有效。很高兴您找到了行之有效的方法。
GreenMatt

5

我需要在PyLog conf文件中使用PC的名称,并且套接字库不可用,但是os库可用。

对于Windows,我使用了:

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

其中defaultValue是防止返回None的字符串


12
COMPUTERNAME是非常Microsoft唯一的环境变量,因此不可移植。
德怀特·斯潘塞

1
是的,但是它确实适用于MS系统,如果合适,它也可以工作。很多时候,当实用性和问题使他们变得无关紧要时,这里的人们过于在速度或平台独立性上纠缠不清。
比尔·基德

7
@BillKidd OP在问题中提到了Windows,OS X和Linux,因此需要系统可移植性是一个非常合理的假设。
zstewart

1
@BillKidd虽然通常应该避免过早的优化或可移植性,但不要使用易于使用且可以说更具可维护性的解决方案,因为它具有更高的可移植性。
疯狂物理学家

2

您必须执行此行代码

sock_name = socket.gethostname()

然后,您可以使用该名称来查找addr:

print(socket.gethostbyname(sock_name))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.