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.