Assume someuser has a home directory /home/someuser
NAME=someuser
In bash - what expression to I use combining tilde (~) and $NAME to return the users home directory?
HOMEDIRECTORY=~someuser
echo $HOMEDIRECTORY
/home/someuser
NAME=someuser
echo ~$NAME
~someuser
any suggestions?
Safer:
eval HOMEDIRECTORY="$(printf "~%q" "$NAME")"
Here the %q
option to printf
quotes and escapes dangerous characters.
If $NAME
is joe, you'd get something like /home/joe
. For root, you might get /root
. For "abc;rm something" you'd get "~abc;rm something" instead of having something removed.
If you have access to getent
:
getent passwd "$NAME" | cut -d: -f 6
Tilde ( ~ ) it's the same as $HOME so, not all the user will have as root to home the same directory.
But if you insist in using the tilde this do the work:
echo ~/../$NAME
See:
$ pwd
/home/oreyes
$ export NAME=john
$ export DIRECTORYNAME=~/../$NAME
$ cd $DIRECTORYNAME
$ pwd
/home/john
Interesting difference between bash and csh, where ~$VARNAME actually does what you'd expect!
This is ugly, but it seems to work in bash:
homedir=`eval "echo ~$USERNAME"`
Now $homedir holds the home directory associated with $USERNAME.
BEST METHOD
Required: nothing
(n.b., this is the same technique as getent without requiring getent)
home() { # returns empty string on invalid user
grep "^$1:" /etc/passwd | cut -d ':' -f 6
}
# grep "^$user:" /etc/passwd | cut -d ':' -f 6
/var/lib/memcached
NICE METHOD FOR ROOT LINUX
Required: Linux, root (or sudo)
home() { # returns errorlevel 1 on invalid user
su "$1" -s '/bin/sh' -c 'echo $HOME'
}
# su memcached -s '/bin/sh' -c 'echo $HOME'
/var/lib/memcached
SOLUTION FOR COMPLETE EXPANSION
magic() { # returns unexpanded tilde express on invalid user
local _safe_path; printf -v _safe_path "%q" "$1"
eval "ln -sf $_safe_path /tmp/realpath.$$"
readlink /tmp/realpath.$$
rm -f /tmp/realpath.$$
}
Example usage:
$ magic ~nobody/would/look/here
/var/empty/would/look/here
$ magic ~invalid/this/will/not/expand
~invalid/this/will/not/expand
METHOD FOR HARNESSING CSH
This is a BASH script, it just calls csh.
Required: csh
home() { # return errorlevel 1 on invalid user
export user=$1; csh -c "echo ~$user"
}
$ export user=root; csh -c "echo ~$user"
/var/root
$ export user=nodfsv; csh -c "echo ~$user"
Unknown user: nodfsv.
METHOD OF DESPERATION
Required: finger (deprecated)
home() {
finger -m "$1" |
grep "^Directory:" |
sed -e 's/^Directory: //' -e 's/ .*//'
}
# finger -m "haldaemon" |
> grep "^Directory:" |
> sed -e 's/^Directory: //' -e 's/ .*//'
/home/haldaemon
You can combined the grep operation into sed, but since this method is sucky, I wouldn't bother.
one alternative way
awk -F":" '{print "user: "$1", Home directory is: "$6}' /etc/passwd