为什么在'cat file1> file2> file3'之后file2为空?

时间:2015-05-17 19:17:44

标签: unix cat

我正在尝试在UNIX上执行以下命令。

$ cat file1>file2>file3

在仅存在file1的情况下,我认为应该发生的是:

    应使用file2,的内容创建
  • file1
  • 然后file3来自file2
  • 的内容

实际发生的是:

  • file2file3已创建并
  • file3的内容为file1
  • file2没有 - file2已创建但空白/空。

有人可以解释为什么会这样吗?

4 个答案:

答案 0 :(得分:6)

shell在运行命令之前从左到右解释文件重定向。所以当你输入

The organizationName field needed to be the same in the
CA certificate (My Own CA Company) and the request (My Customer)

首先进行重定向cat file1 > file2 > file3 - 创建或清空> file2并将stdout指向它。然后它执行file2,创建或清空> file 3并指向stdout。最后,它运行命令file3,该命令读取cat file1并将其复制到stdout。由于stdout(现在)指向file1file3最终成为该副本。由于当stdout指向file3时没有写入任何内容,file2最终为空。

答案 1 :(得分:4)

其他人已经解释了为什么file2为空(但简而言之,这是因为重定向到file3会将重定向替换为file2,因此创建或清空file2但是file3file1获取数据。

如果您想要输出两个文件,请使用tee

cat file1 | tee file2 > file3

还有其他方法可以做到这一点,包括:

tee < file1 file2 > file3

它具有一定的令人愉悦的对称性。它还避免了另一个开放的UUoC(无用的cat)标记。但是,如果您有可变数量的输入文件(0或标准输入,或许多 - 意味着多于一个 - 或者您需要处理命令行参数),那么cat仍然是正确的。请注意,tee可以生成多个文件(因此在某些情况下cat "$@" | tee file1 file2 file3 >/dev/null可能会有意义。)

答案 2 :(得分:2)

strace给出答案。

open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                        = 1
close(3)                          = 0
open("file3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                        = 1
close(3)                          = 0
execve("/bin/cat", ["cat", "file1"], [/* 38 vars */]) = 0

第二个dup2()关闭与file2关联的文件描述符。当cat运行时,它的标准输出是file3。

答案 3 :(得分:1)

那里发生的事情是关于如何管理标准输入/输出。

你有cat file1>file2>file3,它在这里做的几乎与

相同
cat file1 > file3

因为file2将输入重定向到输出

因此,即使您的文件2中包含一些文本并执行

cat file1 >  file2 > file3

file3的内容仍然是file1的内容,为什么?

  

CAT(1)用户   命令CAT(1)

     

NAME          cat - 连接文件并在标准输出上打印

     

说明          将FILE(s),或标准输入连接到标准输出。

检查(或标准输出的标准输入)。您将标准输入从file2直接重定向到标准输出。

让我们来看看这个场景:

  • file1包含&#39; 123&#39;
  • file2包含&#39; 456
  • file3不存在

如果你cat file1 > file2 > file3,那么文件的内容将是

  • file1包含&#39; 123&#39;
  • file2 为空
  • file3包含&#39; 123&#39;

file2向输出发送file1发送到输入的内容