1182

I need to get the location of the home directory of the current logged-on user. Currently, I've been using the following on Linux:

os.getenv("HOME")

However, this does not work on Windows. What is the correct cross-platform way to do this ?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • 7
    This is marked a duplicate of [How to find the real user home directory using python](https://stackoverflow.com/questions/2668909/), but I voted to reopen because this answer works on Python 3 and the older answer does not. – Dour High Arch Jun 17 '20 at 18:40

5 Answers5

2051

You want to use os.path.expanduser.
This will ensure it works on all platforms:

from os.path import expanduser
home = expanduser("~")

If you're on Python 3.5+ you can use pathlib.Path.home():

from pathlib import Path
home = str(Path.home())

But it's usually better not to convert Path.home() to string. It's more natural to use this way:

with open(Path().home() / ".ssh" / "known_hosts") as f:
    lines = f.readlines()
dcolish
  • 22,727
  • 1
  • 24
  • 25
  • 63
    it should be noted that if the user is logged on to a domain on windows and has their profile home folder set in active directory then this will report that mapped network folder instead of the local home directory – scape Dec 17 '12 at 19:18
  • Should anyone just want the home directory rather than the user directory, you might try finding the user directory (`ud`) and doing this: `hd=os.sep.join(ud.split(os.sep)[:-1])` – Brōtsyorfuzthrāx Oct 28 '16 at 09:26
  • I have a CLI application running under sudo and this uses root's home directory instead of the sudoer. Solution here: https://stackoverflow.com/questions/5721529/running-python-script-as-root-with-sudo-what-is-the-username-of-the-effectiv – Preston Badeer Jan 10 '17 at 17:22
  • 19
    I wonder why nobody else mentioned it in this question, but if you need to know where another user's home directory is you can use `os.path.expanduser('~username')`. Probably applies only for Linux though. – Max Jun 28 '18 at 11:56
  • you have to import `pathlib2` instead of `pathlib` to do `path.home()` – Dipayan Jun 14 '19 at 22:48
  • 3
    @Dipayan no, that's the Python 2 backport of pathlib. For Python 3, pathlib is correct. – Haystack Jul 16 '19 at 18:08
  • How do I decide which one to use? – deed02392 Jul 31 '19 at 10:11
  • 3
    The result is the same. If you generally are working with pathlib, you may prefer the pathlib solution (and omit the call of `str`). If you just want the path as string, they both do the same. – Niklas Mertsch Aug 15 '19 at 12:31
  • @IvanDePazCenteno "from Python3.5 onwards" does not seem to have lasted very long. Doesn't work with Python 3.8.6. – UTF-8 Nov 25 '20 at 10:03
  • 1
    Are you sure? Works just fine with 3.9.5 here. – Vampire May 27 '21 at 09:19
  • Thank you very much - this makes my code 1 line shorter because it also works when the `$HOME` environment variable is not set (at least on Linux) – TheEagle Aug 01 '21 at 17:47
  • you can also do `from pathlib import Path; home: str = str(Path('~').expanduser())` – Charlie Parker Jul 28 '22 at 21:06
  • 2
    @dcolish please remove `str()` from the answer. It's so much more natural to build a path with the slash `/` such as `Path.home() / "location_of_a_file.txt". – Paul Rougieux Nov 25 '22 at 16:49
36

I found that pathlib module also supports this.

from pathlib import Path
>>> Path.home()
WindowsPath('C:/Users/XXX')
Jaeyoon Jeong
  • 569
  • 4
  • 8
18

I know this is an old thread, but I recently needed this for a large scale project (Python 3.8). It had to work on any mainstream OS, so therefore I went with the solution @Max wrote in the comments.

Code:

import os
print(os.path.expanduser("~"))

Output Windows:

PS C:\Python> & C:/Python38/python.exe c:/Python/test.py
C:\Users\mXXXXX

Output Linux (Ubuntu):

rxxx@xx:/mnt/c/Python$ python3 test.py
/home/rxxx

I also tested it on Python 2.7.17 and that works too.

Cow
  • 2,543
  • 4
  • 13
  • 25
5

This can be done using pathlib, which is part of the standard library, and treats paths as objects with methods, instead of strings.

from pathlib import Path

home: str = str(Path('~').expanduser())
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Charlie Parker
  • 5,884
  • 57
  • 198
  • 323
-2

This doesn't really qualify for the question (it being tagged as cross-platform), but perhaps this could be useful for someone.

How to get the home directory for effective user (Linux specific).

Let's imagine that you are writing an installer script or some other solution that requires you to perform certain actions under certain local users. You would most likely accomplish this in your installer script by changing the effective user, but os.path.expanduser("~") will still return /root.

The argument needs to have the desired user name:

os.path.expanduser(f"~{USERNAME}/")

Note that the above works fine without changing EUID, but if the scenario previously described would apply, the example below shows how this could be used:

import os
import pwd
import grp

class Identity():

    def __init__(self, user: str, group: str = None):
        self.uid = pwd.getpwnam(user).pw_uid
        if not group:
            self.gid = pwd.getpwnam(user).pw_gid
        else:
            self.gid = grp.getgrnam(group).gr_gid

    def __enter__(self):
        self.original_uid = os.getuid()
        self.original_gid = os.getgid()
        os.setegid(self.uid)
        os.seteuid(self.gid)

    def __exit__(self, type, value, traceback):
        os.seteuid(self.original_uid)
        os.setegid(self.original_gid)

if __name__ == '__main__':

    with Identity("hedy", "lamarr"):
        homedir = os.path.expanduser(f"~{pwd.getpwuid(os.geteuid())[0]}/")
        with open(os.path.join(homedir, "install.log"), "w") as file:
            file.write("Your home directory contents have been altered")
Tammi
  • 421
  • 7
  • 12