![为什么当我在 pwd 中已经有一个名为“~kernel-ppa”的文件夹时,cd ~k (&tab) 会扩展为 cd ~kernoops?](https://linux22.com/image/851859/%E4%B8%BA%E4%BB%80%E4%B9%88%E5%BD%93%E6%88%91%E5%9C%A8%20pwd%20%E4%B8%AD%E5%B7%B2%E7%BB%8F%E6%9C%89%E4%B8%80%E4%B8%AA%E5%90%8D%E4%B8%BA%E2%80%9C~kernel-ppa%E2%80%9D%E7%9A%84%E6%96%87%E4%BB%B6%E5%A4%B9%E6%97%B6%EF%BC%8Ccd%20~k%20(%26tab)%20%E4%BC%9A%E6%89%A9%E5%B1%95%E4%B8%BA%20cd%20~kernoops%EF%BC%9F.png)
我有一个名为~kernel-ppa
inside 的文件夹~/Downloads
。
aditya@aditya-desktop:~$ cd Downloads/
aditya@aditya-desktop:~/Downloads$ ls
~kernel-ppa
现在,当我键入cd ~k
并按下自动扩展时,尽管具有相同起始字符的文件夹已经存在,但Tabshell 仍将其扩展为cd ~kernoops/
而不是。cd ~kernel-ppa/
为了使自动扩展工作,我需要用 对其进行转义\
。因此,使用cd \~k
并按下可以Tab正确将其扩展为cd \~kernel-ppa/
。即使使用cd \
并按下也Tab可以解决问题。
为什么会这样?我为什么要逃避?而且,既然~
自动扩展甚至不需要,我又在逃避什么呢?
如果我顺其自然,运行cd ~kernoops/
并按下Enter,终端状态将更改为//
:
aditya@aditya-desktop:~/Downloads$ cd ~kernoops/
aditya@aditya-desktop://$ pwd
//
aditya@aditya-desktop://$ ls
bin cdrom etc initrd.img lost+found mnt proc run srv tmp var
boot dev home lib media opt root sbin sys usr vmlinuz
aditya@aditya-desktop://$
这看起来像/
目录,但pwd
说它是//
。它到底是什么?
答案1
如您所知,~
会扩展到您的主目录。但您似乎忽略了会~john
扩展到名为“john”的用户的主目录。
检查你的/etc/passwd
文件:
% grep ker /etc/passwd
kernoops:x:107:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
它有一个名为“系统用户” kernoops
(出于内部错误报告的原因)。因此,当您输入时,cd ~k
Tabshell 会优先考虑用户名扩展,而不是本地目录扩展,并且您有cd ~kernoops
。现在结果是用户“kernoops”的主目录是/
,所以它cd
指向它。
在我的 shell 中zsh
,没有双斜线(2):
[:/] % cd ~kernoops/
[:/] % pwd
/
[:/] % cd //
[:/] % pwd
/
另外,这个目录名没有经过深思熟虑。在脚本和其他方面都需要三倍小心。我能想到的唯一最糟糕的想法就是在其中嵌入一个标签...
脚注:
(1)在 中zsh
,即使我有一个名为 的目录~xdir
并且没有以 开头的用户x
;这样做cd ~x
Tab不会扩展并且不引用会出现~
错误:
[:~/tmp/x] % mkdir \~xdir
[:~/tmp/x] % ls
~xdir
[:~/tmp/x] % cd ~xdir
zsh: no such user or named directory: xdir
[:~/tmp/x] 1 %
(2)我似乎记得 posix 对//
路径中的首字母做了一个例外 --- 它应该被保留,因为一些旧的 unix 变体(我使用了亚波罗(与具有该功能的域/操作系统)用于//machine-name/...
无缝访问本地网络中其他机器的文件系统(安全性尚未发明)。所以可能 bash 就在这里。但是,如果你这样做,cd ///
你将在两个 shell 中都正常/
。
是的,在 unix.se 上找到!
答案2
波浪符号 ( ~
) 在 shell 中有特殊含义。当它出现在任何命令中时,它会扩展为您的主目录的名称。执行cd ~
或cd /home/aditya
操作相同,它会以您的主目录结尾。
通过在波浪符号前面放置一个反斜杠字符 ( \
),您可以告诉 shell 不要扩展后面的特殊字符(这就是所谓的 shell 转义)。通过执行此操作,cd \~
您可以要求 shell 移动到名为 的目录~
,该目录位于您正在执行命令的目录下。这样做cd \~kernel-ppa
会将您更改为名为 的目录~kernel-ppa
,这是正常行为。
已编辑:更多信息〜
如果您在 后写入系统的用户名~
,则会转到该用户的主目录。Tab在 后执行扩展cd ~
将扩展到系统上现有的用户名。如果Tab在 后执行完成cd ~k
,它将扩展为 ~kernoops,因为有名为科尔诺普斯在系统用户中,主目录为/
。由于 的扩展cd ~k
结果为 ,cd ~kernoops/
末尾带有斜杠,主目录为/
,因此您将被移动到。但这与其他人之前所说的//
完全相同。/