假设file2
已经存在,该命令
> file1 < file2 cat
似乎是复制的内容file2
来file1
。
但我无法理解这种结构。
我了解“什么都没有”指向file1
(创建或删除其内容)。然后将的内容file2
定向到file1
。
为什么cat
之后file2
呢?如何知道cat file2
操作数的顺序不正确?
假设file2
已经存在,该命令
> file1 < file2 cat
似乎是复制的内容file2
来file1
。
但我无法理解这种结构。
我了解“什么都没有”指向file1
(创建或删除其内容)。然后将的内容file2
定向到file1
。
为什么cat
之后file2
呢?如何知道cat file2
操作数的顺序不正确?
Answers:
在Shell cat
在命令行上执行命令之前,它会查找重定向。
有两个重定向:
>file1
这将使命令的标准输出转到file1
。<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重定向]
<in foo | bar >out
会将所有内容按逻辑顺序放置。我也很喜欢echo >&2 Something bad happened
shell脚本的错误输出。但这>out <in cat
只是混淆
sort file >file
正确完成?
sort -o file file
。
< file1 > file2 cat
会比更好> file2 < file1 cat
,因为这将避免file2
,如果被截断file1
无法打开。