Existe-t-il un moyen de rediriger la sortie vers un fichier sans mettre en tampon sur unix / linux?


49

J'ai un long processus de traitement par lots qui génère des informations de débogage et de processus sur stdout. Si je viens de courir à partir d'un terminal, je peux garder une trace de «où il se trouve», mais les données deviennent trop volumineuses et disparaissent de l'écran.

Si je redirige la sortie vers un fichier '> out.txt', je récupère finalement la totalité de la sortie, mais celle-ci est mise en mémoire tampon afin que je ne puisse plus voir ce qu'elle fait actuellement.

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


1
Pourriez-vous s'il vous plaît jeter un oeil à mon (et au @cnst) "débat" ci-dessous, je suppose que la seule chose que vous voulez, c'est de voir le résultat en même temps que de le consigner dans un fichier. Si vous avez trouvé une solution, faites-le nous savoir;)!
Benj

Réponses:


52

Vous pouvez définir explicitement les options de mise en mémoire tampon des flux standard à l'aide d'un setvbufappel en C (voir ce lien ), mais si vous essayez de modifier le comportement d'un programme existant, essayez stdbuf( coreutilsapparemment à partir de la version 7.5).

Cela tamponne stdoutjusqu'à une ligne:

stdbuf -oL command > output

Cela désactive stdoutcomplètement la mise en mémoire tampon:

stdbuf -o0 command > output

aaarghhh ... Mon Ubuntu n'a que 7,4 coreutils ... :(
Calmarius

@Calmarius: la compilation de coreutils devrait être assez facile. Il suffit de récupérer une nouvelle version sur ftp.gnu.org/gnu/coreutils et de l’ essayer . C'est le ./configure && maketarif standard . Vous n'avez même pas besoin de l'installer après, vous pouvez simplement utiliser le stdbufbinaire off src/.
Eduardo Ivanec

double argh. J'ai besoin de cela sur une ancienne distribution centos ET OSX, ainsi que sur Ubuntu.
Edk750


Existe-t-il un moyen de forcer les tampons pipe / printf en externe pour un processus en cours d'exécution avec un PID connu?
Mvorisek

9

Vous pouvez obtenir une sortie mise en mémoire tampon dans un fichier en utilisant la scriptcommande comme suit:

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

-1 parce que: a) contrairement à la réponse acceptée, cela ne fonctionne pas si vous voulez exécuter la commande en arrière-plan (la commande se termine immédiatement sans terminer batch_processsi vous ajoutez &à la commande ci-dessus, au moins sur ma machine Linux), ce qui semble comme un cas d'utilisation extrêmement courant, et b) il n'y a pas d'explication ici du fonctionnement de cette incantation.
Mark Amery

8

Sur Ubuntu, le unbufferprogramme (à partir du expect-dev) package a fait l'affaire pour moi. Il suffit de courir:

unbuffer your_command

et ça ne va pas le tamponner.


6

La solution la plus simple que j'ai trouvée (aucun logiciel tiers requis n'a été installé) a été mentionnée dans un fil de discussion similaire sur les sites Unix et Linux : utilisez la scriptcommande. Il est vieux 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 de la scriptcommande est le fichier journal à écrire . Si vous exécutez simplement script -q your_command, vous écraserez la commande que vous avez mise en retrait avec le fichier journal. Vérifiez man script, pour être sûr, avant de l'essayer.


4

essayez la scriptcommande; si votre système en dispose, il prend un nom de fichier en argument, tout le texte vidé sur stdout est copié dans le fichier. C'est très utile lorsqu'un programme d'installation nécessite une interaction.


Je connais le truc 'script -a out.txt'. Je me demandais s'il y avait un autre moyen de rendre le processus d'écriture non tampon.
James Dean

3

Personnellement, je préfère canaliser la sortie d'une commande que je souhaite examiner tee.

scriptenregistre trop d'informations, y compris le minutage des appuis sur les touches et de nombreux caractères non imprimables. Ce qui teesauve est pour moi beaucoup plus lisible par l'homme.


J'ajouterais aussi "| less" à la ligne de commande.
HUB

4
Je suis à peu près sûr que cela teeest également affecté par la mise en mémoire tampon. Souvent, je reçois toujours des lignes partielles affichées par té lors du fractionnement de la sortie des findcommandes.
Magellan

2

Rediriger la sortie dans un fichier et suivre le fichier avec la tail -fcommande.

Modifier

Si le problème persiste, utilisez la fonction syslog (généralement non tamponnée). Si le processus de traitement 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 malgré tout y avoir une fonction de journalisation.


3
C’est ce que je fais en ce moment, mais le processus tamponne l’écriture dans le fichier et c’est ce que je veux éviter.
James Dean

Voir mon édition pour une proposition mise à jour.
Wolfgangsz

1
Cela ne fonctionne pas pour des raisons évidentes. Qui diable donne des This answer is usefulréponses qui ne fonctionnent pas et ne peuvent pas fonctionner?
cnst

1

Vous pouvez utiliser la teecommande, tout simplement magique!

someCommand | tee logFile.logseront tous deux affichés dans la console et écrits dans le fichier journal.


Ça ne marche pas teen'empêchera pas la mise en mémoire tampon.
cnst

1
@cnst Effectivement, cela teen'empêchera pas une certaine mise en mémoire tampon mais vous permettra seulement de jeter un coup d'oeil sur ce qui est la sortie. C’est ce que @JamesDean voulait (car j’ai bien compris sa question), mais je pense que la mise en mémoire tampon n’est pas vraiment le problème ici. Si vous avez plus de détails, faites le moi savoir.
Benj

Il voulait voir la sortie, et il ne reçoit aucune sortie (de manière non tamponnée), et pourtant vous suggérez d'utiliser teepour obtenir une meilleure vue de la sortie qu'elle ne reçoit pas?
cnst

1
Comment je réponds à la question @JamesDean: "Je redirige vers la sortie vers un fichier '> out.txt'" signifie pour moi aucune sortie de console, attendez que le processus soit terminé pendant que toute la sortie est redirigée. Lorsque vous utilisez, >vous ne voyez rien sur la console. Je suppose que @JamesDean utilise le mot "mise en mémoire tampon" pour décrire cela. Je posterai un commentaire sur sa question pour qu'il puisse en dire plus sur ce qu'il veut.
Benj
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.