Habituellement, stdout
est tamponné en ligne. En d'autres termes, tant que votre printf
argument se termine par une nouvelle ligne, vous pouvez vous attendre à ce que la ligne soit imprimée instantanément. Cela ne semble pas tenir lorsque vous utilisez un tube vers lequel rediriger tee
.
J'ai un programme C ++,, a
qui génère des chaînes, toujours \n
terminées, vers stdout
.
Lorsqu'il est exécuté seul ( ./a
), tout s'imprime correctement et au bon moment, comme prévu. Cependant, si je le dirige vers tee
( ./a | tee output.txt
), il n'imprime rien tant qu'il ne se ferme pas, ce qui va à l'encontre de l'objectif de l'utilisation tee
.
Je sais que je pourrais le réparer en ajoutant un fflush(stdout)
après chaque opération d'impression dans le programme C ++. Mais existe-t-il un moyen plus simple et plus propre? Existe-t-il une commande que je peux exécuter, par exemple, qui forcerait la mise stdout
en tampon de ligne, même lorsque vous utilisez un tube?
expect
me compiler carunbuffer
ne semble pas être inclus par défaut dans OS X.unbuffer
n'est qu'un petit script, vous n'auriez donc pas dû avoir besoin de recompiler l'ensemble du paquet../configure && make
pris environ 10 secondes, puis je suis passéunbuffer
à/usr/local/bin
:)unbuffer {commands with pipes/tee}
.tu peux essayer
stdbuf
(grande) partie de la page de manuel:
gardez cela à l'esprit, cependant:
vous n'êtes pas en cours d' exécution
stdbuf
surtee
, vous utilisez sura
, donc cela ne devrait pas vous affecter, à moins que vous définissez la mise en mémoire tampon desa
« cours d'eau de dansa
» la source.De plus, ce
stdbuf
n'est pas POSIX, mais fait partie de GNU-coreutils.la source
stdbuf
est déjà disponible sur les distributions Linux Centos que nous utilisons etunbuffer
ne l'est pas. Merci!-u
pour désactiver la mise en mémoire tampon du côté de python:python3 -u a.py | tee output.txt
Vous pouvez également essayer d'exécuter votre commande dans un pseudo-terminal à l'aide de la
script
commande (qui devrait appliquer la sortie tamponnée en ligne au tube)!Sachez que la
script
commande ne propage pas le statut de sortie de la commande encapsulée.la source
script -t 1 /path/to/outputfile.txt ./a
a très bien fonctionné pour mon cas d'utilisation. Il diffuse en direct toutes les sortiesoutputfile.txt
tout en les imprimant sur la sortie standard de votre shell. N'a pas besoin d'utilisertee
Vous pouvez utiliser setlinebuf depuis stdio.h.
Cela devrait changer la mise en mémoire tampon en "ligne tamponnée".
Si vous avez besoin de plus de flexibilité, vous pouvez utiliser setvbuf.
la source
setvbuf(stdout, NULL, _IOLBF, 0)
, ce qui est exactement équivalent.Si vous utilisez les classes de flux C ++ à la place, every
std::endl
est un flush implicite. En utilisant l'impression de style C, je pense que la méthode que vous avez suggérée (fflush()
) est le seul moyen.la source
#include <iostream> #include <unistd.h> int main(void) { std::cout << "1" << std::endl; sleep(1); std::cout << "2" << std::endl; }
. endl vide toujours le tampon comme défini ici: en.cppreference.com/w/cpp/io/manip/endl