Si l'on voulait vraiment ces données, je suggérerais d'attacher le débogueur gdb à l'interpréteur python, d'arrêter momentanément la tâche, d'appeler fsync(1)
( stdout ), de la détacher (reprendre le processus) et d'aller parcourir le fichier de sortie.
Regardez /proc/$(pidof python)/fd
pour voir les descripteurs de fichiers valides. $(pidof x)
renvoie le PID du processus nommé ' x
'.
# your python script is running merrily over there.... with some PID you've determined.
#
# load gdb
gdb
#
# attach to python interpreter (use the number returned by $(pidof python))
attach 1234
#
# force a sync within the program's world (1 = stdout, which is redirected in your example)
call fsync(1)
#
# the call SHOULD have returned 0x0, sync successful. If you get 0xffffffff (-1), perhaps that wasn't stdout. 0=stdin, 1=stdout, 2=stderr
#
# remove our claws from poor python
detach
#
# we're done!
quit
J'ai utilisé cette méthode pour modifier les répertoires de travail, modifier les paramètres à la volée ... beaucoup de choses. Hélas, vous ne pouvez appeler que des fonctions définies dans le programme en cours d'exécution, mais cela fsync
fonctionne bien.
(La commande gdb ' info functions
' répertorie toutes les fonctions disponibles. Attention cependant. Vous utilisez LIVE sur un processus.)
Il y a aussi la commande peekfd
(trouvée dans le psmisc
paquet sur Debian Jessie et autres) qui vous permettra de voir ce qui se cache dans les tampons d'un processus. Encore une fois, /proc/$(pidof python)/fd
vous montrera des descripteurs de fichiers valides à donner comme arguments à peekfd.
Si vous ne vous souvenez pas -u
de python, vous pouvez toujours préfixer une commande avec stdbuf
(in coreutils
, déjà installé) pour définir stdin / stdout / stderr sur non tamponné, ligne tamponnée ou bloc tamponné comme vous le souhaitez:
stdbuf -i 0 -o 0 -e 0 python myscript.py > unbuffered.output
Bien sûr, man pages
sont vos amis, hé! peut-être qu'un alias pourrait également être utile ici.
alias python='python -u'
Maintenant, votre python utilise toujours -u
pour tous vos efforts en ligne de commande!
fileobject.c
) différente de 2.7 . Quelqu'un a besoin de creuser dans leio
module.Il n'y a pas de solution à votre problème immédiat. Si votre script a déjà démarré, vous ne pouvez pas modifier le mode de mise en mémoire tampon après coup. Ce sont tous des tampons en mémoire et tout cela est configuré au démarrage du script, à l'ouverture des descripteurs de fichiers, à la création de canaux, etc.
À long terme, si et seulement si une partie ou la totalité de la mise en mémoire tampon en question est effectuée au niveau IO en sortie, vous pouvez exécuter une
sync
commande; mais cela est généralement peu probable dans un cas comme celui-ci.À l'avenir, vous pouvez utiliser l'
-u
option * de Python pour exécuter le script. En général, de nombreuses commandes ont des options spécifiques aux commandes pour désactiver la mise en mémoire tampon stdin / stdout, et vous pouvez également avoir un certain succès générique avec launbuffer
commande duexpect
package.Un Ctrl+ Centraînerait le vidage des tampons au niveau du système lorsque le programme est interrompu à moins que le tampon ne soit effectué par Python lui-même et qu'il n'ait pas implémenté la logique pour vider ses propres tampons avec Ctrl+ C. Une suspension, un crash ou un kill ne serait pas si gentil.
* Force stdin, stdout et stderr à être totalement sans tampon.
la source
Documentation Python 2.7.7, section "Configuration et utilisation de Python", sous-section 1. Ligne de commande et environnement , décrit cet argument Python:
Et aussi cette variable d'environnement:
la source
sys.stdout.flush()
, mais votre-u
option semble encore plus facile), mais j'avais juste oublié de le faire lors de l'appel de mon code. Ayant déjà exécuté mon code pendant plus d'une semaine, j'espérais qu'il y avait un moyen d'obtenir ma sortie sans avoir besoin de relancer le code pendant une autre semaine.Il semble que j'étais trop prudent à propos de la perte par sortie tamponnée après avoir exécuté Ctrl-C; selon cet article, je dois m'attendre à ce que le tampon soit vidé si mon programme a une sortie normale, ce qui serait le cas si je tapais Ctrl-C. D'un autre côté, je perdrais la sortie tamponnée si je tuais le script avec SIGKILL ou similaire.
la source
Je pense qu'une autre solution possible peut être de forcer le processus à tuer avec le noyau vidé puis à analyser le contenu de la mémoire à titre posthume.
la source