Neo_Returns Asked: 2018-05-18 06:14:25 +0800 CST2018-05-18 06:14:25 +0800 CST 2018-05-18 06:14:25 +0800 CST cd ~<user> 是可能的,但为什么我们不能 cd ~"$USER" 或 cd ~${USER} 772 我很好奇为什么我们不能切换到用户的主目录 $ cd ~"$USER" 或者 $ cd ~${USER} shell command-line 5 个回答 Voted Best Answer Stéphane Chazelas 2018-05-18T06:24:21+08:002018-05-18T06:24:21+08:00 这在很大程度上取决于外壳以及在这些外壳中进行扩展的顺序。 ~$user扩展至用户的主目录,其名称存储在$usercsh(该~user功能的来源)、AT&T ksh、zsh、fish 中。 但是请注意这些变化: $ u=daemon/xxx csh -c 'echo ~$u' /usr/sbin/xxx # same in zsh/fish $ u=daemon/xxx ksh93 -c 'echo ~$u' ~daemon/xxx $ u=daemon/xxx csh -c 'echo ~"$u"' Unknown user: daemon/xxx. $ u=daemon/xxx zsh -c 'echo ~"$u"' /usr/sbin/x # same in fish $ u=" daemon" csh -c 'echo ~$u' /home/stephane daemon $ u=" daemon" zsh -c 'echo ~$u' ~ daemon # same in ksh/fish $ u="/daemon" csh -c 'echo ~$u' /home/stephane/daemon # same in zsh $ u="/daemon" fish -c 'echo ~$u' ~/daemon # same in ksh 它扩展到字面上命名的用户的主目录$user(bash假设用户存在,当然这不太可能)。 并且在pdksh, dash,中都没有yash,大概是因为他们不认为$user是有效的用户名。 Kusalananda 2018-05-18T06:21:37+08:002018-05-18T06:21:37+08:00 波浪号扩展是命令行处理中的一个单独步骤。它发生在变量扩展之前。 如果波浪号后跟斜杠以外的其他内容,它将扩展到名称跟在波浪号后面的用户的主目录,例如,~otheruser. 由于$USER此时未展开并且由于它不太可能对应于有效的用户名,因此波浪号未展开。 $USER可能是当前用户的用户名,因此您的表达式可能会被替换为~. kasperd 2018-05-18T14:23:29+08:002018-05-18T14:23:29+08:00 正如其他答案所指出的那样,行为取决于外壳执行的顺序~和$扩展,以及它是否甚至会为同一个词执行这两种操作。 您正在寻找的行为可以bash通过对您的命令进行非常小的更改来实现。只需在命令前加上eval. eval "cd ~$USER" 将更改为由变量中的用户名给出的用户的主目录USER,前提$USER是不包含 shell 特殊的字符(如果有可能发生这种情况,则不应将其作为参数传递给,eval因为那会很危险) 或/字符,并且系统的用户数据库中有该用户的条目。 zwol 2018-05-18T08:09:19+08:002018-05-18T08:09:19+08:00 如果您使用的是在变量扩展之前发生波浪号扩展的外壳之一,则查找变量用户主目录的另一种方法是使用getent。该工具至少存在于 Linux、Solaris 和 FreeBSD 上;我不确定它有多普遍。 $ USER=bloggs $ getent passwd "$USER" | cut -d: -f6 /home/b/bloggs su - $USER -c 'echo $HOME'与波浪号扩展一样,如果您有权限执行此操作,这可能不会为您提供打印的相同内容。 jamesqf 2018-05-19T17:50:31+08:002018-05-19T17:50:31+08:00 由于OP坚持要答案,所以就在这里。 这些命令(以及许多其他东西)的行为取决于您碰巧使用的特定 shell。除非您指定您使用的特定外壳,否则可能无法给出简单的答案。 事实上,如果您像我一样使用 tcsh,那么 OP 问题中的两个表达式(正如我写这篇文章时所写的那样 - 我对未来的编辑不承担任何责任!)工作得很好。我不知道其他 shell 会做什么,因为我不使用它们。因此,也许 OP 并不像他/她认为的那样了解可以做什么:-)
这在很大程度上取决于外壳以及在这些外壳中进行扩展的顺序。
~$user
扩展至用户的主目录,其名称存储在$user
csh(该~user
功能的来源)、AT&T ksh、zsh、fish 中。但是请注意这些变化:
它扩展到字面上命名的用户的主目录
$user
(bash
假设用户存在,当然这不太可能)。并且在
pdksh
,dash
,中都没有yash
,大概是因为他们不认为$user
是有效的用户名。波浪号扩展是命令行处理中的一个单独步骤。它发生在变量扩展之前。
如果波浪号后跟斜杠以外的其他内容,它将扩展到名称跟在波浪号后面的用户的主目录,例如,
~otheruser
. 由于$USER
此时未展开并且由于它不太可能对应于有效的用户名,因此波浪号未展开。$USER
可能是当前用户的用户名,因此您的表达式可能会被替换为~
.正如其他答案所指出的那样,行为取决于外壳执行的顺序
~
和$
扩展,以及它是否甚至会为同一个词执行这两种操作。您正在寻找的行为可以
bash
通过对您的命令进行非常小的更改来实现。只需在命令前加上eval
.将更改为由变量中的用户名给出的用户的主目录
USER
,前提$USER
是不包含 shell 特殊的字符(如果有可能发生这种情况,则不应将其作为参数传递给,eval
因为那会很危险) 或/
字符,并且系统的用户数据库中有该用户的条目。如果您使用的是在变量扩展之前发生波浪号扩展的外壳之一,则查找变量用户主目录的另一种方法是使用getent。该工具至少存在于 Linux、Solaris 和 FreeBSD 上;我不确定它有多普遍。
su - $USER -c 'echo $HOME'
与波浪号扩展一样,如果您有权限执行此操作,这可能不会为您提供打印的相同内容。由于OP坚持要答案,所以就在这里。
这些命令(以及许多其他东西)的行为取决于您碰巧使用的特定 shell。除非您指定您使用的特定外壳,否则可能无法给出简单的答案。
事实上,如果您像我一样使用 tcsh,那么 OP 问题中的两个表达式(正如我写这篇文章时所写的那样 - 我对未来的编辑不承担任何责任!)工作得很好。我不知道其他 shell 会做什么,因为我不使用它们。因此,也许 OP 并不像他/她认为的那样了解可以做什么:-)