have to determine all users home directories - til

2020-02-29 01:42发布

问题:

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?

回答1:

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.



回答2:

If you have access to getent:

getent passwd "$NAME" | cut -d: -f 6


回答3:

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


回答4:

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.



回答5:

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.



回答6:

one alternative way

awk -F":" '{print "user: "$1", Home directory is: "$6}' /etc/passwd