Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 必须确定所有用户的主目录-tilde脚本问题_Bash_Tilde Expansion - Fatal编程技术网

Bash 必须确定所有用户的主目录-tilde脚本问题

Bash 必须确定所有用户的主目录-tilde脚本问题,bash,tilde-expansion,Bash,Tilde Expansion,假设someuser有一个主目录/home/someuser NAME=someuser 在bash中,我使用什么表达式组合tilde(~)和$NAME来返回用户的主目录 HOMEDIRECTORY=~someuser echo $HOMEDIRECTORY /home/someuser NAME=someuser echo ~$NAME ~someuser 有什么建议吗?另一种方法 awk -F":" '{print "user: "$1", Home directory is: "$6}'

假设someuser有一个主目录/home/someuser

NAME=someuser

在bash中,我使用什么表达式组合tilde(~)和$NAME来返回用户的主目录

HOMEDIRECTORY=~someuser
echo $HOMEDIRECTORY
/home/someuser
NAME=someuser
echo ~$NAME
~someuser
有什么建议吗?

另一种方法

awk -F":" '{print "user: "$1", Home directory is: "$6}' /etc/passwd
Tilde(~)它与$HOME相同,因此,并非所有用户都具有相同目录的根目录

但是,如果您坚持使用瓷砖,请执行以下操作:

echo ~/../$NAME
见:


bash和csh之间的有趣区别是~$VARNAME实际上实现了您所期望的功能

这很难看,但在bash中似乎有效:

homedir=`eval "echo ~$USERNAME"`

现在$homedir保存与$USERNAME关联的主目录。

如果您有权访问
getent

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

更安全

eval HOMEDIRECTORY="$(printf "~%q" "$NAME")"
此处
%q
选项用于
printf
引用和转义危险字符


如果
$NAME
是joe,您将得到类似
/home/joe
的内容。对于root,您可能会得到
/root
。对于“abc;rm something”,您将获得“~abc;rm something”,而不是删除某些内容。

最佳方法

要求:无 (注意,这是与getent相同的技术,无需getent

根LINUX的NICE方法

必需:Linux,root(或sudo

完全扩展的解决方案

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.$$
}
用法示例:

$ magic ~nobody/would/look/here
/var/empty/would/look/here

$ magic ~invalid/this/will/not/expand
~invalid/this/will/not/expand
治理CSH的方法

这是一个BASH脚本,它只调用csh

必填项: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.
绝望的方法

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.$$
}
必需:finger(已弃用)


您可以将grep操作组合到sed中,但由于此方法很糟糕,我不想麻烦。

如果使用LDAP auth,这将失败。您想使用
getent passwd
。它将使用/etc/nsswitch.conf(即:/etc/passwd、nis、ldap等)中配置的任何名称服务交换机数据库。这假定所有用户的主目录(包括当前目录)都是同级目录。如果当前用户是
root
,则此操作将失败得尤其明显。即使不是root,也无法保证。例如,CMU的Andrew上的home是按照
/afs/Andrew.CMU.edu/usr###/$LOGNAME
的模式给出的,其中
##
是一个半随机整数。我喜欢这个简单的解决方案,因为我知道我会在没有根的情况下运行这个案例,这已经足够好了。在bash中确实是这样做的。Tilde扩展发生在参数扩展之前,因此shell实际上尝试将~$USERNAME扩展到用户的主目录中,该用户的名字实际上是$USERNAME,而不是$USERNAME的内容。只需确保
$USERNAME
首先被清除,并且不包含类似
的内容;sudorm-rf/
,“kay?”@ephemient:好建议!我很惊讶“小鲍比桌子”还没出现+1为解决方案。此外,轻微的打字错误:不应该有尾随的严重口音。应该是eval homeditory=“$(printf”~%q“$NAME”)“我喜欢这个解决方案,因为它克服了
eval
的问题,而且整洁、干净、易于阅读和调试。谢谢。这与
getent
不同,因为并非所有用户都存储在
/etc/passwd
中。这对Mac OS X很有帮助,因为并非所有用户都存储在/etc/password中。然而,MacOSX没有附带getent,这使得它成为一个没有实际意义的问题。
$ magic ~nobody/would/look/here
/var/empty/would/look/here

$ magic ~invalid/this/will/not/expand
~invalid/this/will/not/expand
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.
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