How can I use Python to get the system hostname?
Asked Answered
H

12

950

I'm writing a chat program for a local network. I would like be able to identify computers and get the user-set computer name with Python.

Herries answered 24/11, 2010 at 21:33 Comment(0)
E
1447

Use socket and its gethostname() functionality. This will get the hostname of the computer where the Python interpreter is running:

import socket
print(socket.gethostname())
Exotic answered 24/11, 2010 at 21:36 Comment(6)
And note that for the FQDN you can use socket.getfqdn()Laith
Just curious what's the difference between socket.gethostname() and os.uname()[1] or platform.uname()[1]Monnet
is this portable?Incompletion
how to get a hostname without DNS suffix?Langelo
@Langelo On some systems (rhel 7. 9 x86_64) socket.gethostname still returns the full name with FQDN. I used sysName = socket.gethostname().split(".")[0] to get just the short hostname into a variable named 'sysName'Latashialatch
How is this not at the top?Digestion
C
487

Both of these are pretty portable:

import platform
platform.node()

import socket
socket.gethostname()

Any solutions using the HOST or HOSTNAME environment variables are not portable. Even if it works on your system when you run it, it may not work when run in special environments such as cron.

Cryptocrystalline answered 24/11, 2010 at 21:53 Comment(8)
Well, semi-portable. On some platforms, platform.node() gives the fqdn and on others, only the hostnameSixty
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loopRoca
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loopRoca
@BelowtheRadar don't worry, I usually only call either of these once per script.Cryptocrystalline
platform.node() is even faster than os.getenv. gethostname isn't even a contender. But if time isn't a factor: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0] should be cross-platform and support environment variables if they exist - which permits some user control in exigent circumstances, eg HOSTNAME=correct python xyz.pySaki
@Sixty : how does socket.gethostname compare to platform.node in terms of the inconsistency you describe?Draughty
Does anyone know why platform.node() is so much faster than others?Firsthand
@Firsthand platform.node() returns a cached value. socket.gethostname() does not. Example: import platform, socket, subprocess; p = lambda: print(platform.node(), socket.gethostname()); p(); subprocess.run(['sudo', 'hostnamectl', 'set-hostname', foo']); p(). While both functions return the same correct value on the first call, after the hostname has been changed platform.node() still returns the old value.Haight
S
187

You will probably load the os module anyway, so another suggestion would be:

import os
myhost = os.uname()[1]
Synaesthesia answered 13/3, 2013 at 19:6 Comment(9)
+1 for a solution using os module. Not portable and not really accurate, but handy anyway.Getupandgo
os.uname is not supported on Windows: docs.python.org/dev/library/os#os.unameDespair
You can also do os.uname().nodename to make it a bit more obvious in 3.3+Lorna
An answer below gives the similar looking platform.uname()[1], which DOES work on Windows.Jackquelin
@Jackquelin You probably shouldn't use positional words like "below" as answers may have shifted during landing ;)Signalize
why is this not protable?Incompletion
Since os.uname() actually returns a namedtuple one can also do the more descriptive myhost = os.uname().nodenameLubbock
@Charlie Parker: It's not portable since it doesn't work on windows. platform.uname()[1] or platform.node() should work well everywhere.Granddaddy
AttributeError: module 'os' has no attribute 'uname'Yettie
S
79

What about :

import platform

h = platform.uname()[1]

Actually you may want to have a look to all the result in platform.uname()

Shelves answered 2/1, 2012 at 10:14 Comment(3)
Worked on Ubuntu and Windows for me. Thanks! 👍Bimolecular
platform.uname().node is a bit more verbose than platform.uname()[1], I assume it was introduced around the same time as the os.uname equivalent mentioned in another comment.Mythological
This should be the same as platform.node()Improvise
B
65

os.getenv('HOSTNAME') and os.environ['HOSTNAME'] don't always work. In cron jobs and WSDL, HTTP HOSTNAME isn't set. Use this instead:

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

It always (even on Windows) returns a fully qualified host name, even if you defined a short alias in /etc/hosts.

If you defined an alias in /etc/hosts then socket.gethostname() will return the alias. platform.uname()[1] does the same thing.

I ran into a case where the above didn't work. This is what I'm using now:

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

It first calls gethostname to see if it returns something that looks like a host name, if not it uses my original solution.

Bushcraft answered 8/5, 2012 at 15:23 Comment(2)
you probably want socket.getfqdn(), though it is not what the OP asksExpert
socket.gethostbyaddr(socket.gethostname()) on my machine (which is running FreeBSD) returns ('localhost', ['my-machine-name', 'my-machine-namelocaldomain'], ['::1']), so returning the first element just returns localhost. (Meanwhile, socket.gethostname() returns my-machine-name for me.)Eleanoreleanora
C
52

From at least python >= 3.3:

You can use the field nodename and avoid using array indexing:

os.uname().nodename

Although, even the documentation of os.uname suggests using socket.gethostname()

Cognac answered 2/4, 2018 at 12:1 Comment(3)
According to the doc, os.uname is available only on "recent flavors of Unix"Renz
@CharlesPlager Worked for me in Python 3.8.6, RHEL7 container running in OpenShiftAlysaalyse
Not portable, no windows supportOdelsting
N
25

If I'm correct, you're looking for the socket.gethostname function:

>> import socket
>> socket.gethostname()
'terminus'
Nickel answered 24/11, 2010 at 21:37 Comment(0)
D
16

You have to execute this line of code

sock_name = socket.gethostname()

And then you can use the name to find the addr :

print(socket.gethostbyname(sock_name))
Dorene answered 10/3, 2019 at 12:30 Comment(1)
this approach returns just ip for meAngelia
D
14

socket.gethostname() could do

Doghouse answered 24/11, 2010 at 21:38 Comment(0)
H
11

To get fully qualified hostname use socket.getfqdn()

import socket

print socket.getfqdn()
Hannahhannan answered 11/11, 2020 at 2:57 Comment(1)
Yes, but unfortunately sometimes this just returns localhost, and not even the hostname as returned by socket.gethostname().Synclastic
S
9

On some systems, the hostname is set in the environment. If that is the case for you, the os module can pull it out of the environment via os.getenv. For example, if HOSTNAME is the environment variable containing what you want, the following will get it:

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

Update: As noted in the comments, this doesn't always work, as not everyone's environment is set up this way. I believe that at the time I initially answered this I was using this solution as it was the first thing I'd found in a web search and it worked for me at the time. Due to the lack of portability I probably wouldn't use this now. However, I am leaving this answer for reference purposes. FWIW, it does eliminate the need for other imports if your environment has the system name and you are already importing the os module. Test it - if it doesn't work in all the environments in which you expect your program to operate, use one of the other solutions provided.

Saber answered 24/11, 2010 at 21:43 Comment(6)
That returns "None" for me. According to the link you posted, that means the variable 'HOSTNAME' doesn't exist... :-/Herries
@John: Are you on Windows? It worked for me on a Linux box, but I get None on Windows also.Saber
@MuhiaNJoroge: I think that depends on your implementation/installation. When I wrote that answer I was on a Red Hat box and it worked. Now I'm on Ubuntu and it doesn't work. I've modified the answer.Saber
Not work in lenovo NAS, return None. Now i'm using import socket print(socket.gethostname())Talley
@RuiMartins: As I said, it doesn't seem to work everywhere. Glad you found something that works.Saber
This is often a bash variable which you'd need to re-export for Python to access, e.g. start Python with HOSTNAME=$HOSTNAME pythonSlap
M
7

I needed the name of the PC to use in my PyLog conf file, and the socket library is not available, but os library is.

For Windows I used:

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

Where defaultValue is a string to prevent None being returned

Mongoloid answered 9/6, 2015 at 9:50 Comment(5)
COMPUTERNAME is a very Microsoft only environment variable and therefor not portable.Armandarmanda
Yes, but it does work for M.S. systems, and if it fits, it works. Many times people here get too entwined on speed or platform independence when practicality and the question render them irrelevant.Mongoloid
@BillKidd OP mentions Windows, OS X, and Linux in the question, so needing system portability is a very reasonable assumption.Luana
@BillKidd While in general it is true that you should avoid premature optimization or portability, not using a readily available and and arguably more maintainable solution because it is more portable is going to the opposite extreme.Heterosis
socket.gethostname() is better than os.environ['COMPUTERNAME']. Because os.environ['COMPUTERNAME'] do not support long PC name after I used it.Difficile

© 2022 - 2024 — McMap. All rights reserved.