此命令如何合法?“> file1 <file2 cat”


61

假设file2已经存在,该命令

> file1 < file2 cat

似乎是复制的内容file2file1

但我无法理解这种结构。

我了解“什么都没有”指向file1(创建或删除其内容)。然后将的内容file2定向到file1

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


11
什么是“正确顺序”?您能否提供一些描述“正确顺序”的资源/学习资料的链接?
Lightness Races in Orbit

7
在问这样的问题时,应指定外壳;不同的具有不同的边缘情况,尤其是在重定向周围。
chrylis -onstroke

Answers:


117

在Shell cat在命令行上执行命令之前,它会查找重定向。

有两个重定向:

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

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

$ cat <file2 >file1

是相同的

$ <file2 cat >file1

这与

$ <file2 >file1 cat

等¹

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

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

cat如果指定了操作数,它也会从其标准输入中读取-。同样,这仅对cat某些其他实用程序特别(即Shell所做的没有)。要使用cat当前目录中名称 -的文件,请在文件名中添加路径,例如./-

¹ 在某些情况下重定向的顺序仍然很重要;cat <file2 >file1例如,使用时,file1如果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

这差不多是sort使用-o文件指定输出文件名时的操作。


只是为了支持以下声明:重定向可以在命令行的实用程序实际名称之前:

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

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

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


14
@Steve可以自由移动重定向,以使一些命令更清晰,例如,开头带有输入重定向的管道<in foo | bar >out会将所有内容按逻辑顺序放置。我也很喜欢echo >&2 Something bad happenedshell脚本的错误输出。但这>out <in cat只是混淆

2
如何sort file >file正确完成?
seth10'4

11
@setht与sort -o file file
Kusalananda

6
好答案。请注意,顺序很重要。< file1 > file2 cat会比更好> file2 < file1 cat,因为这将避免file2,如果被截断file1无法打开。
斯特凡Chazelas

3
有一点要注意:当使用HTML片段链接到POSIX时,最好指定确切的版本(例如pubs.opengroup.org/onlinepubs/9699919799.2016edition),因为已知片段会在同一规范修订版的版本之间改变(此网站上答案的很多链接(包括我的链接)现在都是错误的,因为片段在2016年版本发布后指向了错误的位置)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.