have to determine all users home directories - til

2020-02-29 01:16发布

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?

6条回答
别忘想泡老子
2楼-- · 2020-02-29 01:48

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.

查看更多
萌系小妹纸
3楼-- · 2020-02-29 01:54

If you have access to getent:

getent passwd "$NAME" | cut -d: -f 6
查看更多
Emotional °昔
4楼-- · 2020-02-29 02:00

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.

查看更多
Evening l夕情丶
5楼-- · 2020-02-29 02:00

one alternative way

awk -F":" '{print "user: "$1", Home directory is: "$6}' /etc/passwd
查看更多
姐就是有狂的资本
6楼-- · 2020-02-29 02:07

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.

查看更多
我命由我不由天
7楼-- · 2020-02-29 02:12

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
查看更多
登录 后发表回答