Il existe une règle générale de mise en mémoire tampon suivie de la bibliothèque d'E / S standard C ( stdio
) que la plupart des programmes Unix utilisent. Si la sortie va vers un terminal, elle est vidée à la fin de chaque ligne; sinon, il n'est vidé que lorsque le tampon (8K sur mon système Linux / amd64; pourrait être différent sur le vôtre) est plein.
Si tous les services publics suivaient la règle générale, vous verriez la sortie retardée dans tous vos exemples ( cat|sed
, cat|tr
et cat|tr|sed
). Mais il y a une exception: GNU cat
ne met jamais sa sortie en mémoire tampon. Soit il n'utilise pas, stdio
soit il modifie la stdio
politique de mise en mémoire tampon par défaut .
Je peux être sûr que vous utilisez GNU cat
et pas un autre Unix cat
parce que les autres ne se comporteraient pas de cette façon. Unix traditionnel cat
a une -u
option pour demander une sortie sans tampon. GNU cat
ignore l' -u
option car sa sortie est toujours sans tampon.
Ainsi, chaque fois que vous avez un tuyau avec un cat
à gauche, dans le système GNU, le passage des données à travers le tuyau ne sera pas retardé. Le cat
ne va même pas ligne par ligne - votre terminal le fait. Pendant que vous tapez une entrée pour cat, votre terminal est en mode "canonique" - basé sur la ligne, avec des touches d'édition comme backspace et ctrl-U vous offrant la possibilité de modifier la ligne que vous avez tapée avant de l'envoyer Enter.
Dans l' cat|tr|sed
exemple, tr
reçoit toujours des données cat
dès que vous appuyez sur Enter, mais tr
suit la stdio
stratégie par défaut: sa sortie va dans un tube, donc elle ne videra pas après chaque ligne. Il écrit dans le deuxième canal lorsque le tampon est plein ou lorsqu'un EOF est reçu, selon la première éventualité.
sed
suit également la stdio
politique par défaut, mais sa sortie va à un terminal, il écrira donc chaque ligne dès qu'il en aura fini avec elle. Cela a un effet sur la quantité que vous devez taper avant que quelque chose n'apparaisse à l'autre extrémité du pipeline - si la sed
mise en mémoire tampon de sa sortie était bloquée, vous devriez taper deux fois plus (pour remplir tr
le tampon de sortie et sed
la sortie de tampon).
GNU sed
a une -u
option, donc si vous inversez l'ordre et l'utilisez, cat|sed -u|tr
vous verrez la sortie apparaître de nouveau instantanément. (L' sed -u
option pourrait être disponible ailleurs mais je ne pense pas que ce soit une ancienne tradition unix comme cat -u
) Pour autant que je sache, il n'y a pas d'option équivalente pour tr
.
Il existe un utilitaire appelé stdbuf
qui vous permet de modifier le mode de mise en mémoire tampon de toute commande qui utilise les stdio
valeurs par défaut. C'est un peu fragile car il sert LD_PRELOAD
à accomplir quelque chose que la bibliothèque C n'a pas été conçue pour prendre en charge, mais dans ce cas, cela semble fonctionner:
cat | stdbuf -o 0 tr '[:lower:]' '[:upper:]' | sed 'p'
cat
mise en mémoire tampon jusqu'à la fermeture de stdin.