Por que esse comando cria um arquivo enormemente grande?

19

Hoje eu estava experimentando algumas operações de acréscimo e, por curiosidade, executei isso (onde file1.txt não estava vazio e file2.txt estava vazio):

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

Quando vi um tempo, pressionei Ctrl+ Cpara finalizar. Até então, o arquivo1.txt tinha centenas de MB.

Mudar os nomes dos arquivos não produz o mesmo efeito; somente quando os arquivos estão nessa ordem é que o redirecionamento infinito acontece. O que exatamente está acontecendo que causa isso?

Matt
fonte

Respostas:

24

Você não pode dizer catpara usar vários padrões dessa maneira, o último redirecionamento tem precedência, portanto:

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

é equivalente a:

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

que obviamente preenche rapidamente o sistema de arquivos, considerando que o arquivo de origem sendo o destino também cresce indefinidamente, desde que file1.txtseja grande o suficiente para não ser lido de uma só vez.

A maioria das catimplementações modernas deve detectar a recursividade e abortar:

Gato Solaris:

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

Gnu cat:

cat: file1.txt: input file is output file

Eles podem ser enganados de qualquer maneira com algo como:

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

Um bom uso não tão inútil de gatos ...

jlliagre
fonte
19
São muitos gatos, miau.
slm
2
Você fez minha cabeça girar, mas respondeu minha pergunta!
Matt
7
E quando eu perguntei sobre isto no Google+ (não obter uma resposta), é marcado automaticamente o meu post com #Cat e #Caturday
Matt
3

Não consegui reproduzir isso em um shell Bash:

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

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

1 arquivo é criado com 0 comprimento, mas então recebo a mensagem acima:

$ 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

Com base na resposta de @ jlliagre, não sei por que estou recebendo os 2 arquivos. Pode ser dependente da catimplementação.

EDIT # 1

@jlliagre atualizou sua resposta para mostrar esse código que ele afirma como equivalente:

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

Então agora eu sei por que estou ficando vazia file2.txt. Esta notação é legal:

>> file2.txt

E criará um arquivo vazio.

slm
fonte
Tente novamente com o file1.txtinício não vazio.
Gilles 'SO- stop be evil'
@ Gilles - Acabei de reler isso e notei, devo ver algo diferente, ainda recebo o erro? Ou você está apenas dizendo que b / c o exemplo na minha resposta está errado? Eu corrigi a resposta BTW.
slm
@Gilles - esse foi o seu voto negativo, não? É apenas por algo específico ou falta de valor da resposta?
slm
1
Não sei por que a sua resposta foi rejeitada, uma para experimentar antes de responder, algo que eu não fiz mim ...
jlliagre
+1; obrigado pela sua experimentação! Estou começando a entender catmelhor os redirecionamentos e o comportamento.
Matt