Les commandes ne tamponnent généralement pas leur entrée. Ils feraient un read()
pour un gros morceau, mais lors de la lecture à partir d'un canal, s'il n'y a pas autant d'octets dans le canal, l' read()
appel système retournera avec autant de caractères qu'il y a et l'application fonctionnera généralement avec cela si elle le peut .
Une exception notable est celle mawk
qui continuera read()
jusqu'à ce que le tampon d'entrée soit plein.
Les applications tamponnent cependant leur sortie (stdout). Le comportement habituel est que si la sortie va vers un tty, alors la mise en mémoire tampon sera ligne par ligne (c'est-à-dire qu'elle ne commencera pas à écrire sur stdout jusqu'à ce qu'elle ait une ligne complète à sortir, ou un bloc plein pour très longue ligne), tandis que pour tous les autres types de fichiers, la mise en mémoire tampon se fait par blocs (c'est-à-dire qu'elle ne commencera à écrire qu'après avoir un bloc plein à écrire (quelque chose comme 4KiB / 8KiB ... dépend du logiciel et du système) )).
Donc, dans votre cas, LongRunningCommand
tamponne probablement sa sortie par blocs (puisque sa sortie est un tube et non un tty), et tr
tamponne probablement sa sortie par ligne car sa sortie est probablement le terminal.
Mais, puisque vous supprimez chaque caractère de nouvelle ligne de sa sortie, il ne sortira jamais de ligne, donc la mise en mémoire tampon sera par bloc.
Ici, vous souhaitez désactiver la mise en mémoire tampon pour les deux LongRunningCommand
et tr
. Sur les systèmes GNU ou FreeBSD:
stdbuf -o0 LongRunningCommand | stdbuf -o0 tr '\n' ,
Notez que si vous souhaitez joindre les lignes avec une virgule, une meilleure approche consiste à utiliser paste -sd , -
. De cette façon, la sortie sera terminée par un caractère de nouvelle ligne (vous devrez probablement toujours désactiver la mise en mémoire tampon).
stdbuf
à LongRunningCommand ou à tr, ou aux deux, différemment?