37

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?

69

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. – Rui F Ribeiro Dec 5 '15 at 17:55
  • @RuiFRibeiro you can't use ~foo with variables in bash. Not directly, anyway. – muru Dec 5 '15 at 18:24
  • 1
    @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. – mikeserv Dec 5 '15 at 19:27
  • 1
    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. – zwol Dec 5 '15 at 21:57
  • 1
    @HagenvonEitzen Colons are forbidden precisely because they have been used to separate fields. – Jenny D Dec 6 '15 at 13:14
9

You can use eval to get someone's home directory.

eval echo "~$USER"

At least for local users this works for sure. I don't know if remote users like LDAP are handled with eval.

  • 1
    No need for eval there. Be careful with your english. – Rui F Ribeiro Dec 5 '15 at 18:02
  • 4
    @nwk an eval is needed. Bash doesn't process ~foo after variable expansion. – muru Dec 5 '15 at 18:23
  • 1
    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. – Rui F Ribeiro Dec 5 '15 at 18:25
  • 3
    @RuiFRibeiro It will work fine with LDAP, just use whatever variable contains your LDAP user's username instead of USER. – muru Dec 5 '15 at 18:34
  • 2
    Don't use this without verifying that $USER expands to just a single string of alphabetic characters. – chepner Dec 6 '15 at 2:43
3

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) {print $6}' "/etc/passwd"

For more complex (remote) systems, getent is the usual command to get users information from the NSS (Name Service Switch libraries) system.

A command of

echo $(getent passwd $USER )| cut -d : -f 6

Will provide equivalent information (if available).

  • 2
    you have ~user for that, and your solution does not contemplate users in more complex systems, like user coming from LDAP where you have to use getent. – Rui F Ribeiro Dec 5 '15 at 17:57
2

If the user doesn't exist, getent will return an error.

Here's a small shell function that doesn't ignore the exit code of getent:

get_home() {
  local result; result="$(getent passwd "$1")" || return
  echo $result | cut -d : -f 6
}

Here's a usage example:

da_home="$(get_home missing_user)" || {
  echo 'User does NOT exist!'; exit 1
}

# Now do something with $da_home
echo "Home directory is: '$da_home'"
1

If you are logged in as root, if you know USER's password, or if the USER has no password, the following is yet another option:

    su -c 'echo ~' ${USER}

Under standard su behavior, if USER is undefined or empty, then su will attempt to run the command as root.

If the value of USER is not a valid user name, then an appropriate error will be raised: su: user <user> does not exist.

There are already plenty of good answers here but this may still help someone.

  • This isn't secure, depending on system config. It runs a process (the shell running echo) as that user, so the user could (for example) ptrace the shell and give you arbitrary output. It's also running in the user's setup, so it's possible that the users shell config files are run (which could also give arbitrary outputs). Or environment loads via pam. Etc. Or just do something as simple as send it a SIGSTOP to make it take forever, effectively DOS attacking your script. – derobert Apr 16 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.