我正在解决文本对于 Linux,我发现我可以找到以“-”开头的文件。所以我用“cat ./-”解决了这个问题,它将 - 作为文件名。但我想知道为什么使用“.-”而不是“./-;”不起作用。由于我不是 Linux 初学者,这个问题可能很愚蠢,但我真的想知道为什么。
我以为 .- 和 ./- 是一样的,但只有文件 ./- 有效,而文件 .- 显示错误,即找不到名为 '.-' 的文件
答案1
对于猫来说,这是一种预期的行为。摘自猫手册:
如果没有 FILE,或者 FILE 为 -,则读取标准输入。
我认为它会在点给出的路径中查找 shell 的 STDIN,但这仅是我的猜测。要完全理解,需要阅读 cat 源代码。
希望我至少指出了正确的方向。
答案2
这是因为路径的解释方式。.
实际上是一个目录(这有点过于简单,但在这里已经足够了)。因此,如果您想访问那里的文件,则需要输入一个。这与您输入的是查找名为的文件但找不到它/
是一样的。相反,您输入的是。使用目录前缀也是如此。/home/USER-
USER-
/home
/home/USER/-
.
另一个答案并没有错,只是与问题无关。您询问的是.-
,这与适用-
于任何不以开头的文件名的相关-
。更清楚一点,问题cat -
是当cat
将-
视为文件时,它会读取 STDIN。它也可以解释为参数,我对这种区别不确定。这就是为什么您必须使用带有.
目录前缀的东西(在这里我们看到从.
技术上讲,这是当前目录的硬文件系统链接。尝试ls -a
或file .
,您会看到如此。这个答案有更多信息)。
一旦你输入了.
, 就会知道你指定的是路径,因为操作系统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 的文件,即与名称 相同的文件-
。