ChatGPT解决这个技术问题 Extra ChatGPT

How to find the real user home directory using python?

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)
You may want to checkout unix command(shortcut): ~user It takes you to home directory of current user. On windows have no idea.
This should be marked a duplicate of How to get the home directory in Python? since that question's accepted answer works on Python 3 and this question's does not.
os.path.expanduser('~')

C
Community

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')

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. :)
@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 ;) ).
This is working in Linux, But not in windows. In windows it just joins the "C:\Documents and settings" to the username passed.
This doesn't solve the problem of the "HOME" variable being wrong. See cadence.com/Community/forums/t/17969.aspx for example
@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).
R
Ru Hasha
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.


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.
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!
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 stackoverflow.com/a/42750492/796858. Thanks!
B
Brian M. Hunt

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

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.
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')
M
Mr.Zeus

home_folder = os.getenv('HOME')

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


at least this not works on win10 coz varible has name HOMEPATH
@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. please try to found here 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
r
ring bearer

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?


Except on Cygwin, in which case both are usually defined, and many times different.
k
khawarizmi

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

J
Julien Spronck

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.


I know you said Mac and Linux, but on Windows _USERNAME was None. For future readers.
from pathlib import Path; Path.home().as_posix() # works in Windows as well. Essentailly the same as Spronck's method, it might be more natural.
Would it be an improvement to make it work with windows is to add or "" ?
A
Axel Schneider

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)

translated how?
Translated to the OS language.
J
Jakob Borg

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, ...


But that would only be Unix(Linux) isn't it?
@ring - yep. Added text to that effect.