SI uno realmente quisiera esos datos, sugeriría adjuntar el depurador gdb al intérprete de python, detener momentáneamente la tarea, llamar fsync(1)
( stdout ), desconectarla (reanudar el proceso) y examinar el archivo de salida.
Mire /proc/$(pidof python)/fd
para ver descriptores de archivo válidos. $(pidof x)
devuelve el PID del proceso llamado ' 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
He usado este método para cambiar los directorios de trabajo, ajustar la configuración sobre la marcha ... muchas cosas. Por desgracia, solo puede llamar a funciones definidas en el programa en ejecución, fsync
aunque funciona bien.
(El comando gdb ' info functions
' enumerará todas las funciones disponibles. Sin embargo, tenga cuidado. Está operando EN VIVO en un proceso).
También está el comando peekfd
(que se encuentra en el psmisc
paquete de Debian Jessie y otros) que le permitirá ver lo que se esconde en las memorias intermedias de un proceso. Nuevamente, /proc/$(pidof python)/fd
le mostraremos descriptores de archivo válidos para dar como argumentos a peekfd.
Si no recuerda -u
para python, siempre puede prefijar un comando con stdbuf
(in coreutils
, ya instalado) para establecer stdin / stdout / stderr en no protegido, bloqueado en línea o bloqueado como lo desee:
stdbuf -i 0 -o 0 -e 0 python myscript.py > unbuffered.output
Por supuesto, man pages
son tus amigos, ¡oye! Tal vez un alias podría ser útil aquí también.
alias python='python -u'
¡Ahora tu python siempre usa -u
para todos tus esfuerzos de línea de comando!
fileobject.c
) que 2.7 . Alguien necesita cavar en elio
módulo.No hay solución a su problema inmediato. Si su script ya comenzó, no puede cambiar el modo de almacenamiento en búfer después del hecho. Todos estos son buffers en memoria y todo eso se configura cuando se inicia el script, se abren los identificadores de archivo, se crean tuberías, etc.
Como una posibilidad remota, si y solo si una parte o la totalidad del almacenamiento intermedio en cuestión se realiza en el nivel IO en la salida, puede hacer un
sync
comando; pero esto es generalmente poco probable en un caso como este.En el futuro, puede usar la
-u
opción * de Python para ejecutar el script. En general, muchos comandos tienen opciones específicas de comando para deshabilitar el almacenamiento en búfer stdin / stdout, y también puede tener cierto éxito genérico con elunbuffer
comando delexpect
paquete.A Ctrl+ Ccausaría que los búferes a nivel del sistema se vacíen cuando el programa se interrumpa a menos que Python realice el almacenamiento en búfer y no haya implementado la lógica para vaciar sus propios búferes con Ctrl+ C. Una suspensión, choque o muerte no sería tan amable.
* Forzar que stdin, stdout y stderr estén totalmente libres de búfer.
fuente
Documentación de Python 2.7.7, sección "Configuración y uso de Python", subsección 1. La línea de comandos y el entorno , describe este argumento de Python:
Y también esta variable de entorno:
fuente
sys.stdout.flush()
, pero su-u
opción parece aún más fácil), pero me había olvidado de hacerlo al invocar mi código. Después de haber ejecutado mi código durante más de una semana, esperaba que hubiera una manera de obtener mi salida sin necesidad de volver a ejecutar el código durante otra semana.Parece que estaba siendo demasiado cauteloso acerca de perder por la salida almacenada después de ejecutar Ctrl-C; De acuerdo con esta publicación , debería esperar que el búfer se vacíe si mi programa tiene una salida normal, que sería el caso si presiono Ctrl-C. Por otro lado, perdería la salida almacenada en búfer si matara el script con SIGKILL o similar.
fuente
Creo que otra posible solución puede ser forzar el proceso de matar con el núcleo descargado y luego analizar póstumamente el contenido de memoria.
fuente