Bash 自动完成给出的文件名与 ls 不同

Bash 自动完成给出的文件名与 ls 不同

刚刚发生了一件极其奇怪的事情。由于严重的错字,我输入了

cp filename.xsl .^?~

是的,没错,点-插入号-问号-波形符!事实比小说更离奇。

事情变得更奇怪了。当我打字时

cat .

然后点击TAB,我得到

./    ../    .^?~

但是当我做时ls -a,我得到

.    ..    .?~

最后,当我这样做时

rm .?~

删除命令这样提示我:

rm: remove write-protected regular file `.\177~'?

在成功删除之前。为什么插入符号的存在减少?

答案1

这是因为插入符号通常用于表示ctrl已按下的键,或者它是一个控制字符。

您实际输入的按键序列是这样的:

cp filename.xsl .ctrl+Vbackspace~Enter

您可能正在尝试将该文件复制到您的主目录 ( ~)。您可以通过输入ctrl+来重复此操作Vbackspace。您会^?在屏幕上看到打印的内容。

您可以查看非打印字符转换为的文件C型像这样转义(这是-b重要的标志,但由于您的文件以点开头,您还需要-a

$ ls -ab
.  ..  .\177~

如果没有 ,-b您只会看到它.?~不是因为它只是省略了^,而是因为任何非优先字符都显示为?。尝试touchctrl+ VEnterfooEnter,然后ls。您将看到的文件将是?foo.然后ls -b就会显示\rfoo.

因此,当您输入时,rm .?~它是匹配的,因为在这种情况下,?您键入的内容被 shell 解释为匹配任何单个字符的通配符,而不是具体的实际问号。您已rm使用别名,rm -i因此它会确认您的操作,并且当它确认时,它会显示 C 样式转义代码。

答案2

该文件名中的奇怪字符(如 所示rm)是字符0177( 0x7Fh / 127d )。这就是Del角色。

Bash 自动补全似乎无法一致地处理它。 ls打印?不可打印字符的 a (默认情况下)。尝试:

$ echo a > .$'\x7f'~
$ ls -b .??
.\177~

rm是有帮助的并打印它的八进制值。

答案3

当您按 TAB 时,shell 会进行某种文件名猜测,它会打印两个字符:“^”和“?”对于八进制 177 的字节。您可以通过按 ctrl-V 然后按 shift-ctrl-? 来获取包含该值的字节的文件名。 (一次三个键)用于测试。

文件名不是点插入号问号波浪号,而是点八进制 177 波浪号。不同的程序选择不同的方式来表示八进制 177 值字节。

相关内容