redirection de chat

11

Supposons qu'un fichier appelé abcexiste dans le répertoire actuel et qu'il contient du texte. Lorsque vous exécutez la commande:

cat abc > abc

Pourquoi le contenu du fichier abcdisparaît-il?
Pourquoi la commande supprime-t-elle le texte et le fichier devient un fichier vide?

Tulsi Kanodia
la source
Et pour les solutions, voir Puis-je cutmodifier un fichier sur place?
Gilles 'SO- arrête d'être méchant'
10
Un pointeur laser est un outil très efficace pour la redirection de chat. </pun>
WBT
Mon chat répond très mal à la redirection ...
Ex Umbris
Pour éviter ce problème, j'utilise un petit shellscript que j'ai appelé chien :cat abc | dog abc
joeytwiddle
Une autre option, si cela ne vous dérange pas la sortie à l'écran, est d'utiliser tee.
Andrea Lazzarotto

Réponses:

27

En raison de l'ordre dans lequel les choses sont faites.

Quand vous faites:

cat abc > abc

>est l'opérateur de redirection de sortie, lorsque le shell le voit, il ouvre le fichier en mode troncature en utilisant O_TRUNCflag avec open(2)ie open("abc", O_TRUNC), donc tout ce qui était dans le fichier disparaîtra. Notez que cette redirection est effectuée en premier par le shell avant l' catexécution de la commande.

Ainsi, lorsque la commande cat abcs'exécute, le fichier abcest déjà tronqué et catle trouvera donc vide.

heemayl
la source
1
Qu'en est-il de chat abc >> abc? Que se passe-t-il alors?
Tulsi Kanodia
2
@TulsiKanodia - qui provoque une boucle infinie. Chaque fois que le chat lit une ligne, il en ajoute une autre avant de passer à la suivante.
user3490
3
Ceci est détecté et empêché. Au lieu de cela, le texte cat: filename: input file is output file(où filenameest le nom de fichier que vous avez choisi) est imprimé sur l'ancienne sortie standard.
UTF-8
@TulsiKanodia Voir unix.stackexchange.com/questions/154903/why-does-cat-xx-loop
Gilles 'SO- arrête d'être mal'
5

Ajout à la réponse de @ heemayl , si vous voulez que le code soit plus clair sur la séquence dans laquelle les choses se passent, vous pouvez simplement mettre les redirections quelconques au début de la commande:

> abc cat abc
l0b0
la source