给出一些相当合理的假设,这是可行的,但它远非显而易见的代码(也不是单行代码):
# Working function - painful, but can you simplify any of it?
# NB: Assumes that ~user does not expand to a name with double spaces or
# tabs or newlines, etc.
expand_tilde()
{
case "$1" in
(\~) echo "$HOME";;
(\~/*) echo "$HOME/${1#\~/}";;
(\~[^/]*/*) local user=$(eval echo ${1%%/*})
echo "$user/${1#*/}";;
(\~[^/]*) eval echo ${1};;
(*) echo "$1";;
esac
}
# Test cases
name1="~/Documents/over enthusiastic"
name2="~crl/Documents/double spaced"
name3="/work/whiffle/two spaces are better than one"
expand_tilde "$name1"
expand_tilde "$name2"
expand_tilde "$name3"
expand_tilde "~"
expand_tilde "~/"
expand_tilde "~crl"
expand_tilde "~crl/"
# This is illustrative of the 'normal use' of expand_tilde function
x=$(expand_tilde "$name1")
echo "x=[$x]"
在我的机器(有用户crl
)上运行时,输出为:
/Users/jleffler/Documents/over enthusiastic
/Users/crl/Documents/double spaced
/work/whiffle/two spaces are better than one
/Users/jleffler
/Users/jleffler/
/Users/crl
/Users/crl/
x=[/Users/jleffler/Documents/over enthusiastic]
该函数tilde_expansion
分别以不同的方式处理各种情况。第一个子句处理一个值~
并简单地替换$HOME
。第二种是偏执狂:~/
被映射到$HOME/
. 第三个处理~/anything
(包括一个空的“任何东西”)。下一个案例处理~user
. 包罗万象的*
处理其他一切。
请注意,代码做出了(似是而非的)假设,即~user
不会扩展为包含任何双空格、任何制表符或换行符(可能还有其他类似空格的字符)的值。如果你不得不面对它,生活将是地狱。
注意chdir()
home directory的答案,它解释了 POSIX 需要~
扩展为 的当前值$HOME
,但~user
扩展为密码数据库中的主目录的值。