Pourquoi cette commande crée-t-elle un fichier extrêmement volumineux?

19

J'expérimentais aujourd'hui avec quelques opérations d'ajout et, dans ma curiosité, j'ai exécuté ceci (où file1.txt n'était pas vide et file2.txt était vide):

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

Quand je l'ai vu prendre un certain temps, j'ai appuyé sur Ctrl+ Cpour y mettre fin. À ce moment-là, file1.txt faisait des centaines de Mo.

Changer les noms de fichiers ne produit pas le même effet; ce n'est que lorsque les fichiers sont dans cet ordre que la redirection infinie se produit. Que se passe-t-il exactement qui cause cela?

Mat
la source

Réponses:

24

Vous ne pouvez pas dire catd'utiliser plusieurs standards de cette façon, la dernière redirection a priorité donc:

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

est équivalent à:

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

ce qui évidemment remplit rapidement le système de fichiers, étant donné que le fichier source étant également la destination se développe indéfiniment à condition qu'il file1.txtsoit suffisamment volumineux pour ne pas être lu immédiatement.

La plupart des catimplémentations modernes devraient détecter la récursivité et abandonner:

Chat Solaris:

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

Chat gnou:

cat: file1.txt: input file is output file

Ils peuvent être dupes de toute façon avec quelque chose comme:

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

Une belle utilisation pas si inutile des chats ...

jlliagre
la source
19
Ça fait beaucoup de chats, miaou.
slm
2
Vous m'avez fait tourner la tête mais vous avez répondu à ma question!
Matt
7
Et quand j'ai posé des questions à ce sujet sur Google+ (je n'ai pas obtenu de réponse), il a automatiquement marqué mon message avec #Cat et #Caturday
Matt
3

Je n'ai pas pu reproduire cela dans un 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 fichier est créé avec une longueur de 0 mais je reçois le message ci-dessus:

$ 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

Sur la base de la réponse de @ jlliagre, je ne sais pas pourquoi je reçois les 2 fichiers. Cela peut dépendre de la catmise en œuvre.

EDIT # 1

@jlliagre a mis à jour sa réponse pour afficher ce code qu'il déclare équivalent:

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

Alors maintenant, je sais pourquoi je reçois le vide file2.txt. Cette notation est légale:

>> file2.txt

Et va créer un fichier vide.

slm
la source
Essayez à nouveau en file1.txtcommençant non vide.
Gilles 'SO- arrête d'être méchant'
@ Gilles - Je viens de relire cela et je l'ai remarqué, devrais-je voir quelque chose de différent, j'obtiens toujours l'erreur? Ou dites-vous simplement que b / c l'exemple de ma réponse est faux? J'ai fixé la réponse BTW.
slm
@ Gilles - c'était votre downvote, non? Est-ce juste pour quelque chose de spécifique ou de manque de valeur de la réponse?
slm
1
Je ne sais pas pourquoi votre réponse a été rejetée, +1 pour avoir expérimenté avant de répondre, quelque chose que je n'ai pas fait moi-même ...
jlliagre
+1; merci pour votre expérimentation! Je commence à mieux comprendre les redirections et les catcomportements.
Matt