- Get home directory in Linux
- 4 Answers 4
- How to Find User’s Home Directory in Linux or Unix
- Ways to Find User’s Home Directory in Linux
- Navigating to the Home Directory Traditionally
- Find User’s Home Directory Using Cd Command
- Obtain user’s home directory
- 7 Answers 7
- os.UserHomeDir()
- How to get HOME, given USER?
- 6 Answers 6
Get home directory in Linux
I need a way to get user home directory in C++ program running on Linux. If the same code works on Unix, it would be nice. I don’t want to use HOME environment value. AFAIK, root home directory is /root. Is it OK to create some files/folders in this directory, in the case my program is running by root user?
Current home directory of user (not named) is ~ is it not? As in cd ~ , mv some_file ~/some_file etc.
@NickBedford — ~ is implemented by the shell, not the kernel or libc. When programming in C++, you need to implement that yourself.
From a programmers point of view, Linux is Unix. It follows the same standards. It just hasn’t been certified by The Open Group. From a users point of view, there is no more difference between Linux and «real» Unix systems, than there is among certified systems.
The HOME environment variable isn’t reliable because it could be changed. R Samuel Klatchko’s answer is more precise. However, you should consider the likelihood that if the user has redefined HOME, maybe they had a reason to do so, and your program would better serve the user’s needs by using that variable.
4 Answers 4
You need getuid to get the user id of the current user and then getpwuid to get the password entry (which includes the home directory) of that user:
#include #include #include struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir;
Note: if you need this in a threaded application, you’ll want to use getpwuid_r instead.
Note though that the getpwuid() man page has this caveat: An application that wants to determine its user’s home directory should inspect the value of HOME (rather than the value getpwuid(getuid())->pw_dir ) since this allows the user to modify their notion of «the home directory» during a login session.
This isn’t a good answer to the original question. This is the shell starting directory set up in /etc/passwd , which may or may not be the user’s (active) home directory. This is useful information, but getenv is the right answer.
Most programs should prefer geteuid() over getuid(). Otherwise, if you run a command through sudo, for example, then it will examine your real user login rather than whichever login to which you sudo’ed.
While considering using seteuid() instead of setuid(), also notice that environment variable will NOT change by sudo. That means if you favor $HOME variable than getpwuid(), you will always get the original user home directory, not the effective user home directoy.
You should first check the $HOME environment variable, and if that does not exist, use getpwuid.
#include #include #include const char *homedir; if ((homedir = getenv("HOME")) == NULL) < homedir = getpwuid(getuid())->pw_dir; >
Also note, that if you want the home directory to store configuration or cache data as part of a program you write and want to distribute to users, you should consider following the XDG Base Directory Specification. For example if you want to create a configuration directory for your application, you should first check $XDG_CONFIG_HOME using getenv as shown above and only fall back to the code above if the variable is not set.
If you require multi-thread safety, you should use getpwuid_r instead of getpwuid like this (from the getpwnam(3) man page):
struct passwd pwd; struct passwd *result; char *buf; size_t bufsize; int s; bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize == -1) bufsize = 0x4000; // = all zeroes with the 14th bit set (1 s = getpwuid_r(getuid(), &pwd, buf, bufsize, &result); if (result == NULL) < if (s == 0) printf("Not found\n"); else < errno = s; perror("getpwnam_r"); >exit(EXIT_FAILURE); > char *homedir = result.pw_dir;
How to Find User’s Home Directory in Linux or Unix
Under a Linux operating system distribution environment, a created/existing system user is associated with a Home directory. The configuration of the Home directory ensures that the files belonging to the currently active Linux user are only accessible to that user unless this user switches to another user account where they will access the Home directory of that switched user.
The files under a Linux Home user directory are specific to the currently active users. The base directory of the Linux operating system is the root (/) directory.
It is from the root (/) directory that we should be able to access the Home (/home) directory.
If you only have a single active user on your Linux operating system environment, dealing with the Home directory is straightforward. The latter statement implies that every created/existing Linux user will have their system username as a directory name under this Linux Home directory.
For instance, listing the directories in the above Home directory lists three other directories to imply that the Linux operating system in question hosts 3 three users.
If we decide to navigate into either of the above Linux user folders, we should first be able to meet the following prerequisite.
It is only by being a sudoer/root user that we can be able to navigate into other Linux users’ Home directories without bumping into permission/access barriers.
From the above display, we have managed to navigate to the Home directory and list the files, folders, and directories associated with user dnyce whose user directory exists within the Home (/home) directory.
The above screen capture also reveals to us the different file permissions associated with the listed files, folders, and directories. The file permissions starting with – e.g – rw-rw-r— , imply that we are dealing with a file and the file permissions starting with d e.g drwxr-xr-x , imply that we are dealing with a folder or directory.
Ways to Find User’s Home Directory in Linux
Before we look at some viable approaches to finding a user’s home directory in Linux, it is important to understand why the Home directory exists. This directory helps differentiate system-wide data from user data such that we do not have to deal with redundancy. Also, important file backup operation becomes flawless.
Navigating to the Home Directory Traditionally
You first need to be sure that the Linux user exists. This approach is a summary of the above-discussed content.
The tilde (~) symbol indicates that we are at the home directory of the currently active user.
The Linux user’s home directory contains directories like Documents, Downloads, Music, Pictures, and Public.
Find User’s Home Directory Using Cd Command
Executing the cd (change directory) command alone should take you to the home directory of the current Linux user.
Another approach is to use cd + tilde (~) should navigate us to the Home directory of the currently logged-in user.
You can also use $HOME command, which takes you to the Home directory as a variable.
Not only do we understand the concept of the Linux user’s home directory, but we can navigate to it from any directory path.
Obtain user’s home directory
Is the following the best way of obtaining the running user’s home directory? Or is there a specific function that I’ve ovelooked?
If the above is correct, does anyone happen to know whether this approach is guaranteed to work on non-Linux platforms, e.g. Windows?
$HOME is not necessarily the user’s home directory. For example, I can write export HOME=/something/else before launching your program. Usually that means I want the program to treat /something/else as my home directory for some reason, and usually the program should accept that. But if you really need the user’s actual home directory, an environment variable won’t necessarily give it to you.
7 Answers 7
Since go 1.12 the recommended way is:
package main import ( "os" "fmt" "log" ) func main() < dirname, err := os.UserHomeDir() if err != nil < log.Fatal( err ) >fmt.Println( dirname ) >
In go 1.0.3 ( probably earlier, too ) the following works:
package main import ( "os/user" "fmt" "log" ) func main() < usr, err := user.Current() if err != nil < log.Fatal( err ) >fmt.Println( usr.HomeDir ) >
Be aware that as of go 1.1, «usr, err := user.Current()» will throw a «user: Current not implemented on darwin/amd64» error on osx.
Please DO NOT USE THIS, use os.UserHomeDir() instead, as it takes into consideration a user’s environment variables and the XDG Base Directory Specification! See the answer below for details.
os.UserHomeDir()
In go1.12+ you can use os.UserHomeDir()
That should work even without CGO enabled (i.e. FROM scratch ) and without having to parse /etc/passwd or other such nonsense.
I hope enough people read-down this list because THIS is the function that should be used, as it takes into consideration a user’s environment variables and the XDG Base Directory Specification!
This would even better if you use os.UserCacheDir() and os.UserConfigDir(); particularly for people with home directories on the likes of NFS or using roaming profiles etc.
package main import ( "fmt" "os" "runtime" ) func UserHomeDir() string < if runtime.GOOS == "windows" < home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") if home == "" < home = os.Getenv("USERPROFILE") >return home > return os.Getenv("HOME") > func main()
In almost all cases where I see this used, this is NOT the right thing to do. USERPROFILE is the root of the User’s storage space on the system, but it is NOT the place where applications should be writing to outside of a save dialog prompt. If you have application config, it should be written to APPDATA and if you have application cache (or large files that shouldn’t sync over a network) it should be written to LOCALAPPDATA on Windows.
How to get HOME, given USER?
I have an USER variable in my script, and I want to see his HOME path based on the USER variable. How can I do that?
6 Answers 6
There is a utility which will lookup user information regardless of whether that information is stored in local files such as /etc/passwd or in LDAP or some other method. It’s called getent .
In order to get user information out of it, you run getent passwd $USER . You’ll get a line back that looks like:
[jenny@sameen ~]$ getent passwd jenny jenny:*:1001:1001:Jenny Dybedahl:/home/jenny:/usr/local/bin/bash
Now you can simply cut out the home dir from it, e.g. by using cut, like so:
[jenny@sameen ~]$ getent passwd jenny | cut -d: -f6 /home/jenny
getent is the better answer, specially with remote user. in simpler systems ~user should be enough. Modded you up.
@muru — that’s true — and is spec’d behavior. the ~ does seem to tab-expand, though, and another spec’d behavior of the tilde-prefix shall be replaced by a pathname of the initial working directory associated with the login name obtained using the getpwnam() function and so probably that lookup is pretty good. i dont like tab-expansions, though — i like to type tabs.
Note that this only gets you the initial value of $HOME; the user’s login scripts are perfectly entitled to change it to something else. This is an unusual thing to do, but I can think of situations where it would be sensible, e.g. choosing between a local and an NFS-mounted homedir.
You can use eval to get someone’s home directory.
At least for local users this works for sure. I don’t know if remote users like LDAP are handled with eval .
Interesting, thanks, however this only gets the directory of the current user, not of other users. I think LDAP users are not handled, though I can be wrong.
@RuiFRibeiro It will work fine with LDAP, just use whatever variable contains your LDAP user’s username instead of USER .
Don’t use this without verifying that $USER expands to just a single string of alphabetic characters.
The usual place is /home/$USER , but that does not have to be universal. The definitive place to search for such information is inside the file /etc/passwd .
That file is world readable (anyone could read it), so any user has access to its contents.
If the $USER exists in the file, the entry previous to last is the user HOME directory.
This will select the entry and print the HOME directory:
awk -v FS=':' -v user="$USER" '($1==user) ' "/etc/passwd"
For more complex (remote) systems, getent is the usual command to get users information from the NSS (Name Service Switch libraries) system.
getent passwd "$USER" | cut -d : -f 6
Will provide equivalent information (if available).