为什么“file ./-”有效,但“file .-”无效

为什么“file ./-”有效,但“file .-”无效

我正在解决文本对于 Linux,我发现我可以找到以“-”开头的文件。所以我用“cat ./-”解决了这个问题,它将 - 作为文件名。但我想知道为什么使用“.-”而不是“./-;”不起作用。由于我不是 Linux 初学者,这个问题可能很愚蠢,但我真的想知道为什么。

我以为 .- 和 ./- 是一样的,但只有文件 ./- 有效,而文件 .- 显示错误,即找不到名为 '.-' 的文件

答案1

对于猫来说,这是一种预期的行为。摘自猫手册:

如果没有 FILE,或者 FILE 为 -,则读取标准输入。

我认为它会在点给出的路径中查找 shell 的 STDIN,但这仅是我的猜测。要完全理解,需要阅读 cat 源代码。

希望我至少指出了正确的方向。

答案2

这是因为路径的解释方式。.实际上是一个目录(这有点过于简单,但在这里已经足够了)。因此,如果您想访问那里的文件,则需要输入一个。这与您输入的是查找名为的文件但找不到它/是一样的。相反,您输入的是。使用目录前缀也是如此。/home/USER-USER-/home/home/USER/-.

另一个答案并没有错,只是与问题无关。您询问的是.-,这与适用-于任何不以开头的文件名的相关-。更清楚一点,问题cat -是当cat-视为文件时,它会读取 STDIN。它也可以解释为参数,我对这种区别不确定。这就是为什么您必须使用带有.目录前缀的东西(在这里我们看到从.技术上讲,这是当前目录的硬文件系统链接。尝试ls -afile .,您会看到如此。这个答案有更多信息)。

一旦你输入了., 就会知道你指定的是路径,因为操作系统cat没有什么特别之处,或者像 一样。然后,你需要斜线(第一部分说明了原因)。.cat-

答案3

./-是名称 的相对路径-,但.-是不同的名称。一些实用程序会-特殊处理该字符串,并使用它来引用标准 IO 流之一,但从文件系统的角度来看, 并没有什么特别之处-。同样,./a引用与 相同的文件,a并将./.a命名为与 相同的文件.a.-引用与 相同的文件,而(很可能)与或./.-引用的文件不同。请考虑:-./-

$ touch - # Create a file named '-'
$ touch .- # Create a file named '.-'
$ ls -a
-   ./  .-  ../
$ make_content() { printf 'inode: %s\n' "$(ls -i $1)" > $1; }
$ make_content .-  # write data into '.-'
$ make_content -   # write data into '-'
$ cat ./-   # Display content of -
inode: 57464057 -
$ cat ./.-   # Display content of .-
inode: 57464058 .-
$ cat .-   # Display content of .- again
inode: 57464058 .-
$ echo foo | cat -  # Consume stdin (cat treats - specially)
foo
$ rm .-  # Remove the name .-
$ ls -a
-   ./  ../
$ ln - .-  # Create .-, a reference to the same file as the name -
$ ls -ia - .-   # Show that both .- and - now reference the same file
57464057 -   57464057 .-
$ cat .-   # Show the content of that file
inode: 57464057 -

该实用程序会特别cat处理该字符串-,并且不会将其视为文件名。相反,它会将参数解释-为使用其输入流的指令。此行为的标准解决方法(实际上,标准解决方法是制定不命名文件的策略-,但这是另一个讨论)是使用较长的./-文件名称。 cat不会将字符串./-视为读取 stdin 的指令,而是将其视为文件名。

我已包含 inode 列表以证明在ln操作之后,名称.--都指向完全相同的文件。这与您的问题完全无关,但我觉得有必要澄清为什么我在解释中写了“最有可能”。请记住,传递给实用程序的参数(例如)cat只是字符串。目录中的名称不是文件,它们(大多数)只是字符串。在上述情况下,touch -在文件系统中创建了一个文件(inode 为 57464057;如果您在计算机上尝试此操作,几乎肯定会得到不同的数字)并touch .-创建了一个不同的文件(inode 为 57464058)。调用 会从当前目录中rm .-删除该名称.-,此后不再有任何对 inode 为 57464058 的文件的引用(除非在此 shell 会话之外运行的其他进程创建了链接)。然后,该ln操作在当前目录中创建名称.-。此目录条目引用 inode ...057 的文件,即与名称 相同的文件-

相关内容