Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 为什么文件2在';cat文件1>;文件2>;文件3';?_Unix_Cat - Fatal编程技术网

Unix 为什么文件2在';cat文件1>;文件2>;文件3';?

Unix 为什么文件2在';cat文件1>;文件2>;文件3';?,unix,cat,Unix,Cat,我试图在UNIX上执行以下命令 $ cat file1>file2>file3 在只存在文件1的场景中,我认为应该发生的是: 应使用file1的内容创建file2 然后从file2的内容中选择file3 实际情况是: file2和file3创建并 file3的内容为file1 但是file2没有-file2已创建,但它是空的 有人能解释为什么会发生这种情况吗?strace给出了答案 open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666)

我试图在UNIX上执行以下命令

$ cat file1>file2>file3
在只存在
文件1
的场景中,我认为应该发生的是:

  • 应使用
    file1
    的内容创建
    file2
  • 然后从
    file2
    的内容中选择
    file3
实际情况是:

  • file2
    file3
    创建并
  • file3
    的内容为
    file1
  • 但是
    file2
    没有-
    file2
    已创建,但它是空的

有人能解释为什么会发生这种情况吗?

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。

这里发生的是关于如何管理标准输入/输出的

您有
cat file1>file2>file3
,它在这里的作用与

cat file1 > file3
因为file2将其输入重定向到输出

因此,即使您的file2中有一些文本,并且您执行

cat file1 >  file2 > file3
文件3的内容仍然是文件1的内容,为什么

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

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

描述 将文件、或标准输入连接到标准输出。

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

让我们假设这个场景:

  • 文件1包含“123”
  • 文件2包含“456”
  • 文件3不存在
如果执行
cat file1>file2>file3
,则文件的内容将

  • 文件1包含“123”
  • 文件2是空的
  • 文件3包含“123”

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

在运行命令之前,shell将从左到右解释文件重定向。所以当你进去的时候

cat file1 > file2 > file3

它首先执行重定向
>file2
——创建或清空
file2
,并将stdout指向它。然后它执行
>文件3
,创建或清空
文件3
,并将stdout指向那里。最后,它运行命令
catfile1
,读取
file1
,并将其复制到stdout。由于stdout(现在)指向
file3
file3
最终是它的副本。由于stdout指向
file2
时没有写入任何内容,因此
file2
最终为空。

其他人解释了
file2
为空的原因(简单地说,这是因为重定向到
file3
取代了重定向到
file2
,因此
file2
被创建或清空,但
file3
file1
获取数据)

如果希望输出为两个文件,请使用
tee

cat file1 | tee file2 > file3
还有其他方法可以做到这一点,包括:

tee < file1 file2 > file3
teefile3

它具有某种令人愉悦的对称性。它还避免了UUoC(无用的使用
cat
)标记,而另一个标记是开放的。但是,如果您有数量可变的输入文件(0或标准输入,或多个-意味着不止一个-或您需要处理命令行参数)请注意,
tee
可以生成多个文件(因此在某些情况下,
cat“$@”| tee file1 file2 file3>/dev/null
).

file2
在命令执行后将始终为空,因为重定向会清除它。你是对的。我在测试和执行
cat file1>>file2>file3
时拼写错误,这就是为什么我认为它仍然会保留其内容