Neo*_*rns 8 command-line shell
我很好奇为什么我们不能切换到用户的主目录
$ cd ~"$USER"
Run Code Online (Sandbox Code Playgroud)
或者
$ cd ~${USER}
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 20
这在很大程度上取决于外壳以及在这些外壳中进行扩展的顺序。
~$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
Run Code Online (Sandbox Code Playgroud)
它扩展到字面上名为$userin的用户的主目录bash(假设用户存在,这当然不太可能)。
并且在pdksh, dash, 中yash都没有,大概是因为它们不认为$user是有效的用户名。
Kus*_*nda 10
波浪号扩展是命令行处理中的一个单独步骤。它发生在变量扩展之前。
如果波浪号后跟不是斜杠的东西,它将扩展到名字跟在波浪号后面的用户的主目录,例如,~otheruser。由于此时$USER未展开,并且不太可能对应于有效的用户名,因此波浪号未展开。
$USER可能是当前用户的用户名,因此您的表达式可能仅替换为~.
正如其他答案所指出的那样,行为取决于 shell 执行的顺序~和$扩展,以及它是否甚至会为同一个单词执行这两种操作。
您正在寻找的行为可以bash通过对您的命令进行非常小的更改来实现。只需在命令前面加上eval.
eval "cd ~$USER"
Run Code Online (Sandbox Code Playgroud)
将更改为变量中用户名给出的用户的主目录USER,前提$USER是不包含 shell 特有的字符(如果它可能存在的可能性很小,则不应将其作为参数传递给 ,eval因为那样会很危险) 或/字符,并且系统的用户数据库中有该用户的条目。