这个命令怎么合法呢? "> 文件 1 < 文件 2 猫"

这个命令怎么合法呢? "> 文件 1 < 文件 2 猫"

假设file2已经存在,则命令

> file1 < file2 cat

似乎正在将内容复制file2file1

但我无法理解这个结构。

我了解“无”的目的是file1(创建或删除其内容)。然后 的内容file2将被定向到file1

为什么是cat之后file2?它如何知道cat file2操作数的顺序是否不正确?

答案1

shellcat在命令行上执行命令之前,它会处理所有重定向。重定向包括使用<(stdin,只读),<>(stdin,读+写),>(stdout,只写)和>>(stdout,只写,附加输出)重定向输入或输出,还包括<<word(here-documents)和<<<'...'(在某些 shell 中,“here-strings”)。这些重定向运算符应不加引号,以具有重定向输入或输出的效果,并且您可以在前面添加一个数字来指定要重定向的文件描述符,而不是默认值(stdin (0) 或 stdout (1),具体取决于运算符)。

您显示的命令中有两个重定向:

  1. >file1 这将使命令的标准输出转到file1.
  2. <file2 这将使命令的标准输入来自file2.

事实上,这些重定向被放置在命令行上一个不稳定的位置并不重要。

$ cat <file2 >file1

是相同的

$ <file2 cat >file1

这与以下相同

$ <file2 >file1 cat

等等 ¹

请注意,cat所有这些实例中的实用程序都会执行没有任何命令行参数。重定向不是cat命令的操作数,它们是 shell 的指令,用于设置进出命令的重定向(将其标准输入和输出连接到文件)。 shell 设置重定向调用命令。

cat filecat <file(或者,如果您愿意的话, )之间的区别<file cat在于,在第一种情况下,cat实用程序本身打开文件(该文件在命令行上作为操作数给出)以进行读取,而在第二种情况下,实用程序本身将打开文件以进行读取。将打开文件并将cat的输入流连接到它²。在第二种情况下,cat会注意到它没有给出文件操作数,并且会自动切换到从其标准输入读取。这是cat以及其他一些实用程序的一个功能,并非所有实用程序都具有此功能。

cat如果给定了操作数,也会从其标准输入中读取-。再次强调,这仅对cat某些其他实用程序而言是特殊的(即没有什么是特殊的)做)。用于cat当前目录中其名称的文件 -,添加文件名路径,例如./-.

1在某些情况下,重定向的顺序仍然很重要;例如cat <file2 >file1file1如果无法访问,则不会被截断file2(重定向从左到右解析)。然而,该词的相对位置cat仍然是任意的,不会影响这一点。

²另见问题cat 在打开不存在的文件时给出不同的错误


事实上,shell 在命令行上执行命令之前就设置了重定向,这就是为什么此类操作会失败并且最终得到一个空的输出文件的原因:

$ sort file >file

在这里,shell 将file在执行sort file并将 的标准输出连接sort到文件之前截断(清空)文件。然后该sort实用程序将打开file并排序其内容(什么也没有)。结果(无)通过标准输出流传递到file.

在这种特殊情况下(用于“就地”对文件进行排序)的补救措施是

$ sort -o file file

或者

$ sort file >file.sorted && mv file.sorted file

或者,为了确保原始文件不被删除(以保留某些文件元数据),

$ cp file file.unsorted && sort file.unsorted >file && rm -f file.unsorted

这或多或少是sort使用-o文件指定输出文件名时的作用。


只是为了支持重定向可能位于命令行上实用程序的实际名称之前的声明(我的重点):

“简单命令”是一系列可选的变量分配和重定向,以任何顺序,可选地后跟单词和重定向,由控制运算符终止。[参考:POSIX Shell 命令语言 2.9.1 简单命令]

还有关于重定向不属于实用程序操作数的一部分:

可选数字、重定向运算符和单词不得出现在提供给要执行的命令的参数中(如果有)。[参考:POSIX Shell 命令语言 2.7 重定向]

相关内容