我正在尝试在UNIX上执行以下命令。
$ cat file1>file2>file3
在仅存在file1
的情况下,我认为应该发生的是:
file2
,的内容创建file1
file3
来自file2
。实际发生的是:
file2
和file3
已创建并file3
的内容为file1
file2
没有 - file2
已创建但空白/空。有人可以解释为什么会这样吗?
答案 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(现在)指向file1
,file3
最终成为该副本。由于当stdout指向file3
时没有写入任何内容,file2
最终为空。
答案 1 :(得分:4)
其他人已经解释了为什么file2
为空(但简而言之,这是因为重定向到file3
会将重定向替换为file2
,因此创建或清空file2
但是file3
从file1
获取数据。
如果您想要输出两个文件,请使用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直接重定向到标准输出。
让我们来看看这个场景:
如果你cat file1 > file2 > file3
,那么文件的内容将是
file2向输出发送file1发送到输入的内容