WENN Wenn jemand diese Daten wirklich haben möchte, würde ich vorschlagen, die gdb anzuhängen Debugger an den Python-Interpreter, stoppt vorübergehend die Aufgabe und ruft fsync(1)
auf (stdout ), trennen Sie sich davon (setzen Sie den Prozess fort) und sehen Sie sich die Ausgabedatei an.
Schauen Sie in /proc/$(pidof python)/fd
nach um gültige Dateideskriptoren anzuzeigen. $(pidof x)
gibt die PID des Prozesses mit dem Namen 'x
zurück '.
# 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
Ich habe diese Methode verwendet, um Arbeitsverzeichnisse zu ändern, Einstellungen im Handumdrehen zu optimieren ... viele Dinge. Leider können Sie nur Funktionen aufrufen, die im laufenden Programm definiert sind, fsync
funktioniert aber gut.
(gdb-Befehl 'info functions
' listet alle verfügbaren Funktionen auf. Seien Sie jedoch vorsichtig. Sie arbeiten LIVE in einem Prozess.)
Es gibt auch den Befehl peekfd
(gefunden in psmisc
Paket auf Debian Jessie und anderen), mit dem Sie sehen können, was sich in den Puffern eines Prozesses verbirgt. Wieder /proc/$(pidof python)/fd
zeigt Ihnen gültige Dateideskriptoren, die Sie peekfd als Argumente übergeben können.
Falls Sie sich nicht an -u
erinnern für Python können Sie einem Befehl immer stdbuf
voranstellen (in coreutils
, bereits installiert), um stdin/stdout/stderr wie gewünscht auf ungepuffert, zeilengepuffert oder blockgepuffert zu setzen:
stdbuf -i 0 -o 0 -e 0 python myscript.py > unbuffered.output
Natürlich man pages
sind deine Freunde, hey! vielleicht wäre auch hier ein Alias sinnvoll.
alias python='python -u'
Jetzt verwendet Ihr Python immer -u
für all Ihre Bemühungen auf der Kommandozeile!
Stellen Sie zunächst sicher, dass Sie die Debugging-Symbole für Python (oder zumindest glibc) haben. Auf Fedora können Sie sie installieren mit:
dnf debuginfo-install python
Hängen Sie dann gdb an zum laufenden Skript und führen Sie die folgenden Befehle aus:
[[email protected] ~]$ pidof python2
9219
[[email protected] ~]$ gdb python2 9219
GNU gdb (GDB) Fedora 7.7.1-13.fc20
...
0x00007fa934278780 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) call fflush(stdout)
$1 = 0
(gdb) call setvbuf(stdout, 0, 2, 0)
$2 = 0
(gdb) quit
A debugging session is active.
Inferior 1 [process 9219] will be detached.
Quit anyway? (y or n) y
Detaching from program: /usr/bin/python2, process 9219
Dadurch wird stdout geleert und deaktivieren Sie auch die Pufferung. Die 2
aus dem setvbuf
call ist der Wert von _IONBF
auf meinem System. Sie müssen herausfinden, was auf Ihrem ist (ein grep _IONBF /usr/include/stdio.h
sollte reichen).
Basierend auf dem, was ich in der Implementierung von PyFile_SetBufSize
gesehen habe und PyFile_WriteString
in CPython 2.7 sollte es ziemlich gut funktionieren, aber ich kann keine Garantien abgeben.
Es gibt keine Lösung für Ihr unmittelbares Problem. Wenn Ihr Skript bereits gestartet wurde, können Sie den Puffermodus nicht nachträglich ändern. Dies sind alles In-Memory-Puffer und all das wird eingerichtet, wenn das Skript startet, Datei-Handles geöffnet, Pipes erstellt werden usw.
Kurz gesagt, wenn und nur wenn ein Teil oder die gesamte fragliche Pufferung auf der IO-Ebene bei der Ausgabe erfolgt, könnten Sie einen sync
ausführen Befehl; aber das ist in einem solchen Fall im Allgemeinen unwahrscheinlich.
In Zukunft können Sie Pythons -u
verwenden Option zum Ausführen des Skripts. Im Allgemeinen haben viele Befehle befehlsspezifische Optionen zum Deaktivieren der stdin/stdout-Pufferung, und Sie können auch mit unbuffer
allgemeinen Erfolg haben Befehl von expect
Paket.
Eine Strg +C würde dazu führen, dass Puffer auf Systemebene geleert werden, wenn das Programm es sei denn unterbrochen wird die Pufferung wird von Python selbst durchgeführt und es hat nicht die Logik implementiert, um seine eigenen Puffer mit Ctrl zu leeren +C . Ein Suspend, Crash oder Kill wäre nicht so freundlich.
Fordere stdin, stdout und stderr auf, vollständig ungepuffert zu sein.