为什么这个命令会创建一个非常大的文件?

为什么这个命令会创建一个非常大的文件?

我今天正在尝试一些追加操作,出于好奇,我运行了这个(其中文件1.txt是非空的并且文件2.txt是空的):

$ cat file1.txt >> file2.txt >> file1.txt

当我看到它需要一段时间时,我按Ctrl+C结束它。到时,文件1.txt大小为数百 MB。

切换文件名不会产生相同的效果;仅当文件按此顺序排列时才会发生无限重定向。到底是什么原因导致了这种情况呢?

答案1

您无法cat以这种方式使用多个标准,最后一个重定向优先,因此:

cat file1.txt >> file2.txt >> file1.txt

相当于:

>> file2.txt ; cat file1.txt >> file1.txt

考虑到作为目标的源文件也会无限增长,只要它file1.txt足够大而无法立即读取,这显然会很快填满文件系统。

大多数现代cat实现应该检测递归性并中止:

索拉里斯猫:

cat: input/output files 'file1.txt' identical

牛羚猫:

cat: file1.txt: input file is output file

无论如何,他们可能会被类似的东西愚弄:

cat < file1.txt | cat | cat  >> file2.txt >> file1.txt

对猫的一种很好的利用,但并非毫无用处......

答案2

我无法在 Bash shell 中重现这一点:

# non-empty file1
$ echo 1 > file1.txt

$ cat file1.txt >> file2.txt >> file1.txt 
cat: file1.txt: input file is output file

创建了 1 个长度为 0 的文件,但随后我收到上述消息:

$ ls -l
total 4
-rw-rw-r-- 1 saml saml   2 Sep 10 19:35 file1.txt
-rw-rw-r-- 1 saml saml   0 Sep 10 19:35 file2.txt

根据 @jlliagre 的回答,我不确定为什么会收到这两个文件。这可能取决于cat实施。

编辑#1

@jlliagre 更新了他的答案以显示他所说的等效代码:

>> file2.txt ; cat file1.txt >> file1.txt

所以现在我知道为什么我会得到空的了file2.txt。这种表示法是合法的:

>> file2.txt

并会创建一个空文件。

相关内容