假设我执行以下命令:
tr a-z A-Z < file > file
有两种重定向:< file
和> file
。两者都是在tr
命令之前处理的,据我所知,如果有多个重定向,那么它们是从左到右处理的。换句话说,先有< file
后有> file
。是否< file
只是意味着如果命令启动,则stdin
来自名为 的文件file
?然后> file
处理该部分,这意味着输出将发送到名为file
.名为的文件也file
被截断为零大小。现在终于开始了命令(tr
在我的示例中),但由于输入文件在上一步中被截断为零,那么它只是处理一个空文件?
答案1
这是正确的。>
在命令启动之前截断文件,因此该命令会看到一个空的输入文件。从左到右执行重定向实际上并不重要(除非如果文件不存在,您会收到错误,而>file <file
会首先创建文件)。
somecommand <file >>file
大多数情况下,当命令读取自己的输入时,您会遇到无限循环。但是,对于短文件,该命令可能会在写出任何内容之前检测到输入的结尾,在这种情况下,这将表现为输入和输出是单独的文件。
有了somecommand <file 1<>file
,情况就更复杂了。根据命令是扩展还是缩小文件,它可能会也可能不会在自己的输入上循环。如果该命令总是缩小文件(例如,grep
没有行编号或着色之类的东西),即如果输出的字节 N 始终仅取决于输入的字节 0..N-1,则其行为就像两个文件不同一样。但我不建议依赖它:它在很多方面都很脆弱,如果命令在中间被中断,就会造成混乱。
答案2
使用相同的文件作为输入和输出肯定会给您带来问题。一旦 shell 打开这两个文件,问题就会开始,因为输出文件将被截断。
如果附加到输出,那么它将无限循环,直到磁盘已满或达到最大文件大小。