Bash 必须确定所有用户的主目录-tilde脚本问题
假设someuser有一个主目录/home/someuser NAME=someuser 在bash中,我使用什么表达式组合tilde(~)和$NAME来返回用户的主目录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}'
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