J'ai un programme qui écrit sur la sortie standard et erreur (en C89, printf et fprintf (stderr)). Ce programme est lancé depuis bash. Je récupère la sortie avec ./programme &> log et je suis le fichier depuis une autre console avec tail -f log.
J'ai remarqué que le fichier log n'est pas à jour pendant le lancement du programme. Il me semble que la sortie de printf reste quelque part dans un buffer et est mis à jour quand le programme se termine. Cela m'empêche de suivre avec tail -f pendant l'exécution.
Est-ce que cela a quelque chose à voir avec le shell ? Puis-je forcer bash (ou un autre shell à votre convenance) à écrire immédiatement la sortie qu'il récupère ? J'ai essayé de taper sync sur la ligne de commande mais cela n'aide pas. Merci pour votre aide.
# simple
Posté par TheBreton . Évalué à 5.
A l'endroit de ton programme ou tu souhaite que l'ecriture soit active tu rajoute fflush(stdout) ou fflush(NULL) si tu veut aussi que tous les flux de sortie de ton programme soit synchro (stderr et stdout)
[^] # Re: simple
Posté par solsTiCe (site web personnel) . Évalué à 6.
setbuf(stdout, (char *)NULL);
[^] # Re: simple
Posté par JGO . Évalué à 1.
[^] # Re: simple
Posté par nicolas . Évalué à 2.
[^] # Re: simple
Posté par JoeltheLion (site web personnel) . Évalué à 0.
[^] # Re: simple
Posté par neologix . Évalué à 8.
- _IONBF : pas de bufferisation, on appelle tout de suite l'appel système write
- _IOLBF : bufferisation par ligne, on appelle write lorsqu'on rencontre '\n', utilisée par défaut lorsque le descripteur de fichier est lié à un tty (sauf stderr qui est _IONBF)
- _IOFBF : bufferisation complète, on bufferise jusqu'à ce que le buffer soit plein, utilisé par défaut pour les fichiers, les pipes, etc
Même sans bufferisation, une écriture via printf/fwrite n'entraine pas forcément un accès au disque, le noyau utilise le page cache pour des questions de performance. Pour forcer l'écriture sur disque (commit), il faut passer un un fflush pour flusher le buffer au niveau de la libc, mais aussi un fsync pour forcer un commit des données en cache.
Entre autres choses, la bufferisation au niveau de la libc permet de réduire le nombre d'appels systèmes, qui coutent cher.
La grosse différence c'est que tant qu'il y a des données bufferisées au niveau de la libc (FILE *), les modifications ne sont pas visibles par les autres processus. Par contre dès que write(2) est appelé, elles deviennent visibles.
# c'est normal il me semble
Posté par NeoX . Évalué à 4.
2°) il me semble que les sorties asynchrones que tu as sont liés à la maniere de faire tes printf et fprintf.
De memoire il faut un retour à la ligne pour que ca le valide et que ca l'affiche "vraiment".
sinon ca attend la fin du programme ou le prochain retour à la ligne.
[^] # Re: c'est normal il me semble
Posté par JGO . Évalué à 2.
[^] # Re: c'est normal il me semble
Posté par nicolas . Évalué à 2.
# Pas besoin de tail
Posté par liberforce (site web personnel) . Évalué à 8.
./programme 2>&1 | tee log
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.