Explication simplifiée
Comme de nombreux utilitaires, ce n'est pas quelque chose de particulier à un programme, grep
sa sortie standard varie entre être mise en mémoire tampon de ligne et entièrement mise en mémoire tampon . Dans le premier cas, les tampons de la bibliothèque C produisent des données en mémoire jusqu'à ce que le tampon contenant ces données soit rempli ou qu'un caractère de saut de ligne y soit ajouté (ou que le programme se termine proprement), après quoi il appelle write()
pour réellement écrire le contenu du tampon. Dans ce dernier cas, seul le tampon en mémoire saturé (ou le programme se terminant proprement) déclenche le write()
.
Explication plus détaillée
C'est l'explication bien connue, mais légèrement erronée. En fait, la sortie standard n'est pas mise en mémoire tampon de ligne mais mise en mémoire tampon intelligente dans la bibliothèque GNU C et la bibliothèque BSD C. La sortie standard est également vidée lorsque la lecture de l' entrée standard épuise son tampon en mémoire (d'entrée pré-lue) et la bibliothèque C doit appeler read()
pour récupérer plus d'entrée et elle lit le début d'une nouvelle ligne. (Une des raisons pour cela est d'empêcher un blocage lorsqu'un autre programme se connecte aux deux extrémités d'un filtre et s'attend à pouvoir fonctionner ligne par ligne, en alternant entre l'écriture sur le filtre et la lecture de celui-ci; comme les "coprocesses" dans GNU awk
par exemple.)
Influence de la bibliothèque C
grep
et les autres utilitaires le font - ou, plus strictement, les bibliothèques C qu'ils utilisent le font, car c'est une caractéristique définie de la programmation en langage C - en fonction de ce qu'ils détectent être leur sortie standard. Si (et seulement si) ce n'est pas un appareil interactif, ils choisissent la mise en mémoire tampon complète, sinon ils choisissent la mise en mémoire tampon intelligente. Un canal n'est pas considéré comme un périphérique interactif, car la définition d'un périphérique interactif, au moins dans le monde d'Unix et de Linux, est essentiellement l' isatty()
appel renvoyant true pour le descripteur de fichier correspondant.
Solutions de contournement pour désactiver la mise en mémoire tampon complète
Certains utilitaires comme grep
ont des options idiosyncratiques telles que celles --line-buffered
qui modifient cette décision, qui, comme vous pouvez le voir, est mal nommée. Mais une fraction infiniment petite des programmes de filtrage que l'on pourrait utiliser a en fait une telle option.
Plus généralement, on peut utiliser des outils qui creusent dans les internes spécifiques de la bibliothèque C et changent sa prise de décision (qui ont des problèmes de sécurité si le programme à modifier est set-UID, et sont également spécifiques à des bibliothèques C particulières, et en fait sont spécifiques aux programmes écrits en ou superposés au langage C), ou à des outils tels que ptybandage
ceux -ci qui ne modifient pas les internes du programme mais simplement interposent un pseudo-terminal en sortie standard afin que la décision apparaisse comme "interactive", pour affecter cela.
Lectures complémentaires
cat
concatène les fichiers. Qu'essayez-vous de faire en jouantcat
?