J'essayais de modifier rapidement un .hgignore
fichier du shell bash Cygwin aujourd'hui, et j'ai ajouté une ligne qui était une erreur. Je ne sais pas si c'était la meilleure façon de le faire, mais j'ai rapidement pensé à utiliser head -1 .hgignore
pour supprimer la ligne incriminée (je n'avais auparavant qu'une seule ligne dans le fichier). Effectivement, lorsqu'il est exécuté, il donne la première ligne comme seule sortie.
Mais quand j'ai essayé de rediriger la sortie et de réécrire le fichier en utilisant head -1 .hgignore > .hgignore
, le fichier était vide. Pourquoi cela arrive-t-il? Si j'essaie d'ajouter à la place, head -1 .hgignore >> .hgignore
, il s'ajoute correctement mais ce n'est évidemment pas le résultat souhaité. Pourquoi une redirection tronquante ne fonctionne-t-elle pas dans ce cas ?
Réponse acceptée :
Lorsque le shell reçoit une ligne de commande du type :command > file.out
le shell lui-même ouvre (et peut-être crée) le fichier nommé file.out
. Le shell définit le descripteur de fichier 0 sur le descripteur de fichier de fichier qu'il a obtenu de l'open. C'est ainsi que fonctionne la redirection d'E/S :chaque processus connaît les descripteurs de fichier 0, 1 et 2.
La partie difficile à ce sujet est comment pour ouvrir file.out
. La plupart du temps, vous voulez file.out
ouvert en écriture à l'offset 0 (c'est-à-dire tronqué) et c'est ce que le shell a fait pour vous. Il a tronqué .hgignore, l'a ouvert en écriture, a doublé le filedescriptor à 0, puis a exécuté head
. Encombrement instantané des fichiers.
En bash shell, vous faites un set noclobber
pour changer ce comportement.