web-dev-qa-db-fra.com

Existe-t-il un moyen de rediriger la sortie vers un fichier sans mise en mémoire tampon sous Unix / Linux?

J'ai un processus par lots de longue durée qui génère des informations de débogage et de processus sur stdout. Si je viens de courir depuis un terminal, je peux garder une trace de "où il est", mais les données deviennent trop et défilent sur l'écran.

Si je redirige vers une sortie vers un fichier '> out.txt', j'obtiens finalement toute la sortie, mais elle est mise en mémoire tampon afin que je ne puisse plus voir ce qu'elle fait en ce moment.

Existe-t-il un moyen de rediriger la sortie sans l'empêcher de mettre ses écritures en mémoire tampon?

50
James Dean

Vous pouvez définir explicitement les options de mise en mémoire tampon des flux standard à l'aide d'un appel setvbuf en C (voir ce lien ), mais si vous essayez de modifier le comportement d'un programme existant, essayez stdbuf (une partie de coreutils commençant apparemment avec la version 7.5).

Cela met en mémoire tampon stdout jusqu'à une ligne:

stdbuf -oL command > output

Cela désactive complètement la mise en mémoire tampon de stdout:

stdbuf -o0 command > output
53
Eduardo Ivanec

Vous pouvez obtenir une sortie mise en mémoire tampon de ligne dans un fichier en utilisant la commande script comme ceci:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr
9
melder

Sur Ubuntu, le programme unbuffer (du expect-dev) le paquet a fait l'affaire pour moi. Exécutez simplement:

unbuffer your_command

et il ne le tamponnera pas.

8
Calmarius

La solution la plus simple que j'ai trouvée (ne nécessitant aucun package tiers installé) a été mentionnée dans un thread similaire sur nix & Linux site: utilisez la commande script. Il est ancien et probablement déjà installé.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

Notez que le premier paramètre de nom de fichier pour la commande script est le fichier journal à écrire . Si vous exécutez simplement script -q your_command, vous écraserez la commande que vous avez mise en retrait pour exécuter avec le fichier journal. Vérifier man script, pour être sûr, avant de l'essayer.

6
Steve HHH

essayez la commande script; si votre système l'a, il prend un nom de fichier comme argument, tout le texte sauvegardé dans stdout est copié dans le fichier. Il est très utile lorsqu'un programme d'installation nécessite une interaction.

4
Chris S

Personnellement, je préfère la sortie de tuyauterie d'une commande que je veux examiner via tee.

script enregistre trop d'informations, y compris le timing des pressions sur les touches, et beaucoup de caractères non imprimables. Ce que tee enregistre est beaucoup plus lisible pour moi.

3
Paweł Brodacki

Redirigez la sortie dans un fichier et suivez le fichier avec le tail -f commande.

Modifier

Si cela souffre toujours de la mise en mémoire tampon, utilisez la fonction syslog (qui est généralement sans tampon). Si le processus par lots s'exécute en tant que script Shell, vous pouvez utiliser la commande logger pour ce faire. Si le travail par lots s'exécute dans un langage de script, il devrait tout de même y avoir une fonction de journalisation.

2
wolfgangsz

Vous pouvez utiliser la commande tee, juste magique!

someCommand | tee logFile.log sera les deux s'affiche dans la console et écrit dans le fichier journal.

1
Benj