tr
semble mettre en mémoire tampon son entrée afin que cette commande LongRunningCommand|tr \\n ,
ne commence à produire une sortie qu'après l'accumulation de quelques kilo-octets d'entrée de LongRunningCommand.
Existe-t-il un moyen de forcer l' tr
arrêt de cette mise en mémoire tampon ou toute autre commande pouvant remplacer les sauts de ligne par un autre caractère sans mise en mémoire tampon?
PS J'ai déjà essayé les deux premières suggestions de Turn off buffering in pipe sans succès.
stdbuf
à LongRunningCommand ou à tr, ou aux deux, différemment?stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
fping -q
dit "Ne montrez pas les résultats par sonde, mais seulement le résumé final", alors peut-être qu'il n'y a qu'une longue écriture à la fin?tr
. Essayez|stdbuf -i0 -o0 tr ...
Réponses:
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 continueraread()
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), ettr
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
ettr
. Sur les systèmes GNU ou FreeBSD: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).la source
sed
. désolé si c'était ennuyeux - mais je ne savais pas que c'était des connaissances générales. je suppose qu'il utilise LD_PRELOAD.Pour remplacer les sauts de ligne par
","
, vous pouvez exécuterGNU awk (
gawk
) et Solarisnawk
s'exécuteront avec la mise en mémoire tampon de ligne sur stdin et sans mise en mémoire tampon stdout lorsque la sortie est vers un terminal. Si votre awk l'estmawk
, ce qui se produit sur Ubuntu, vous pouvez lui donner la-W interactive
possibilité d'obtenir ce même comportement de mise en mémoire tampon.la source