93

I see that if we change the HOME (linux) or USERPROFILE (windows) environmental variable and run a python script, it returns the new value as the user home when I try

os.environ['HOME']
os.exp

Is there any way to find the real user home directory without relying on the environmental variable?

edit:
Here is a way to find userhome in windows by reading in the registry,
http://mail.python.org/pipermail/python-win32/2008-January/006677.html

edit:
One way to find windows home using pywin32,

from win32com.shell import shell,shellcon
home = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, None, 0)
djvg
  • 11,722
  • 5
  • 72
  • 103
asdfg
  • 2,541
  • 2
  • 26
  • 25
  • You may want to checkout unix command(shortcut): `~user` It takes you to home directory of current user. On windows have no idea. – mAm Apr 19 '10 at 16:06
  • This should be marked a duplicate of [How to get the home directory in Python?](https://stackoverflow.com/questions/4028904/) since that question's accepted answer works on Python 3 and this question's does not. – Dour High Arch Jun 23 '20 at 19:52
  • 1
    `os.path.expanduser('~') ` – CodeMed Jun 21 '22 at 21:08

9 Answers9

109

I think os.path.expanduser(path) could be helpful.

On Unix and Windows, return the argument with an initial component of ~ or ~user replaced by that user‘s home directory.

On Unix, an initial ~ is replaced by the environment variable HOME if it is set; otherwise the current user’s home directory is looked up in the password directory through the built-in module pwd. An initial ~user is looked up directly in the password directory.

On Windows, HOME and USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used. An initial ~user is handled by stripping the last directory component from the created user path derived above.

If the expansion fails or if the path does not begin with a tilde, the path is returned unchanged.

So you could just do:

os.path.expanduser('~user')
Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 3
    True, but changing the environment variable as in the question will "fool" this method as well. Now, why one would want to do that, I can't say. :) – Jakob Borg Apr 19 '10 at 16:08
  • 1
    @calmh: Yes, I changed it to use `'~user'` which should work on Linux and Windows (here I am not 100% sure because I don't have Windows to test it ;) ). – Felix Kling Apr 19 '10 at 16:10
  • 1
    This is working in Linux, But not in windows. In windows it just joins the "C:\Documents and settings" to the username passed. – asdfg Apr 20 '10 at 08:23
  • This doesn't solve the problem of the "HOME" variable being wrong. See http://www.cadence.com/Community/forums/t/17969.aspx for example – endolith Mar 19 '12 at 00:00
  • 1
    @asdfg : It sounds to me like it worked correctly. But I too thought it had failed the first time I tried, because at first I was passing the literal string '~user' (which really needs to be something literal such as '~Bob') instead of just '~' (which appends the current user). – Jon Coombs Jan 30 '14 at 16:05
  • This doesn't work the way you want it (the code at least). – PascalVKooten Oct 11 '17 at 13:31
  • 1
    `os.path.expanduser('~') ` – CodeMed Jun 21 '22 at 21:07
31
from pathlib import Path

str(Path.home())

works in Python 3.5 and above. Path.home() returns a Path object providing an API I find very useful.

Ru Hasha
  • 876
  • 1
  • 7
  • 16
Julius Kunze
  • 1,035
  • 11
  • 20
  • 2
    Internally, `pathlib` still relies on environment variables, so this does not answer your specific question. Since the more general questions were all marked as duplicates and refer to here, this might be the best place for this answer. – Julius Kunze Jan 28 '17 at 22:25
  • pathlib is my go to library for path handling now! Didn't know about .home(). I will have to revisit the docs again to review all the goodness. Cheers! – PlacidLush Jan 12 '19 at 20:27
  • using pathlib Path.home() would be great except for when python is being run as `sudo` on Linux or Mac. Is there a way to get the `SUDO_USER` environment variable to get the "original" username using Path.home()? If not, then this post seems like a solution https://stackoverflow.com/a/42750492/796858. Thanks! – AdamE Sep 09 '21 at 00:54
18

I think os.path.expanduser(path) is the best answer to your question, but there's an alternative that may be worth mentioning in the Unix world: the pwd package. e.g.

import os, pwd

pwd.getpwuid(os.getuid()).pw_dir
Brian M. Hunt
  • 81,008
  • 74
  • 230
  • 343
  • 1
    This is useful when you want the home directory of the user, but the HOME environment variable is incorrectly set. As the author noted, it's not platform-independent but is rather for UNIX, not Windows. – user1071847 Jun 23 '16 at 21:49
  • 1
    This is better than relying on HOME env variable which may or may not be preserved across sudo calls. For example HOME env. variable is set to target's user in Debian 8 ('sudo' acts as 'sudo -H') but is preserved in Ubuntu 16 ('sudo' acts as 'sudo -E') – Andrei Korostelev May 17 '17 at 17:13
6

For windows;

import os
homepath = os.path.expanduser(os.getenv('USERPROFILE'))

will give you a handle to current user's home directory and

filepath = os.path.expanduser(os.getenv('USERPROFILE'))+'\\Documents\\myfile.txt'

will give you a handle to below file;

C:\Users\urUserName\Documents\myfile.txt
khawarizmi
  • 593
  • 5
  • 19
5

home_folder = os.getenv('HOME')

This should work on Windows and Mac OS too, works well on Linux.

Mr.Zeus
  • 424
  • 8
  • 25
  • 1
    at least this not works on win10 coz varible has name HOMEPATH – Reishin Sep 08 '16 at 07:48
  • @Reishin that's not quite true, I just tested it and it works on Windows 10 Pro. I really don't think they can afford to change the name of an environment variable on a whim, given the amount of software that expects to find it by that name. – s.m. Mar 24 '17 at 10:11
  • @s.m. please try to found here https://technet.microsoft.com/en-us/library/cc749104(v=ws.10).aspx "HOME" variable. If you have custom variable, that not means all ppl have it. In most common, such like mingw, cygwin, git shell, etc...setting it for you. But if you run cmd.exe, you would be surprised – Reishin Mar 25 '17 at 06:28
4

Really, a change in environment variable indicates that the home must be changed. So every program/script should have the new home in context; also the consequences are up to the person who changed it. I would still stick with home = os.getenv('USERPROFILE') or os.getenv('HOME')

what exactly is required?

ring bearer
  • 20,383
  • 7
  • 59
  • 72
4

I realize that this is an old question that has been answered but I thought I would add my two cents. The accepted answer was not working for me. I needed to find the user directory and I wanted it to work with and without sudo. In Linux, my user directory is "/home/someuser" but my root directory is "/root/". However, on my Mac, the user directory is "/Users/someuser". Here is what I ended up doing:

_USERNAME = os.getenv("SUDO_USER") or os.getenv("USER") 
_HOME = os.path.expanduser('~'+_USERNAME)

This worked both with and without sudo on Mac and Linux.

Julien Spronck
  • 15,069
  • 4
  • 47
  • 55
1

get (translated) user folder names on Linux:

from gi.repository import GLib

docs = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)
desktop = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
pics = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
videos = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
music = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
downloads = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
public = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)
templates = GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)

print(docs)
print(desktop)
print(pics)
print(videos)
print(music)
print(downloads)
print(public)
print(templates)
0

On Linux and other UNIXoids you can always take a peek in /etc/passwd. The home directory is the sixth colon-separated field in there. No idea on how to do better than the environment variable on Windows though. There'll be a system call for it, but if it's available from Python, ...

Jakob Borg
  • 23,685
  • 6
  • 47
  • 47