JIKA seseorang benar-benar menginginkan data itu, saya sarankan melampirkan gdb debugger ke juru bahasa python, menghentikan tugas sejenak, memanggil fsync(1)
(stdout ), lepaskan darinya (melanjutkan proses) dan baca dengan teliti file keluaran.
Lihat di /proc/$(pidof python)/fd
untuk melihat deskriptor file yang valid. $(pidof x)
mengembalikan PID dari proses bernama '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
Saya telah menggunakan metode ini untuk mengubah dir yang berfungsi, men-tweak pengaturan dengan cepat ... banyak hal. Sayangnya, Anda hanya dapat memanggil fungsi yang ditentukan dalam program yang sedang berjalan, fsync
bekerja dengan baik.
(perintah gdb 'info functions
' akan mencantumkan semua fungsi yang tersedia. Berhati-hatilah. Anda sedang mengoperasikan LIVE pada suatu proses.)
Ada juga perintah peekfd
(ditemukan di psmisc
paket pada Debian Jessie dan lainnya) yang akan memungkinkan Anda untuk melihat apa yang bersembunyi di buffer suatu proses. Sekali lagi, /proc/$(pidof python)/fd
akan menampilkan deskriptor file yang valid untuk diberikan sebagai argumen ke peekfd.
Jika Anda tidak ingat -u
untuk python, Anda selalu dapat mengawali perintah dengan stdbuf
(dalam coreutils
, sudah diinstal) untuk menyetel stdin/stdout/stderr ke unbuffered, line buffered atau block buffered sesuai keinginan:
stdbuf -i 0 -o 0 -e 0 python myscript.py > unbuffered.output
Tentu saja, man pages
adalah temanmu, hei! mungkin sebuah alias juga berguna di sini.
alias python='python -u'
Sekarang python Anda selalu menggunakan -u
untuk semua upaya baris perintah Anda!
Pertama pastikan Anda memiliki simbol debug untuk Python (atau setidaknya glibc). Di Fedora Anda dapat menginstalnya dengan:
dnf debuginfo-install python
Kemudian lampirkan gdb ke skrip yang sedang berjalan dan jalankan perintah berikut:
[[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
Ini akan menyiram stdout dan juga menonaktifkan buffering. 2
dari setvbuf
panggilan adalah nilai dari _IONBF
pada sistem saya. Anda harus mencari tahu apa yang ada di tangan Anda (sebuah grep _IONBF /usr/include/stdio.h
harus melakukan trik).
Berdasarkan apa yang saya lihat dalam implementasi PyFile_SetBufSize
dan PyFile_WriteString
di CPython 2.7, ini seharusnya bekerja dengan cukup baik, tetapi saya tidak dapat memberikan jaminan apa pun.
Tidak ada solusi untuk masalah langsung Anda. Jika skrip Anda sudah dimulai, Anda tidak dapat mengubah mode buffering setelah kejadian tersebut. Ini semua adalah buffer dalam memori dan semuanya disiapkan saat skrip dimulai, pegangan file dibuka, pipa dibuat, dll.
Sebagai gambaran panjang, jika dan hanya jika beberapa atau semua buffering yang dipermasalahkan dilakukan pada level IO pada keluaran, Anda dapat melakukan sync
memerintah; tetapi umumnya tidak mungkin dalam kasus seperti ini.
Di masa mendatang, Anda dapat menggunakan -u
Python opsi untuk menjalankan skrip. Secara umum, banyak perintah memiliki opsi khusus perintah untuk menonaktifkan buffering stdin/stdout, dan Anda mungkin juga berhasil secara umum dengan unbuffer
perintah dari expect
paket.
A Ctrl +C akan menyebabkan buffer tingkat sistem dibilas saat program diinterupsi kecuali buffering dilakukan oleh Python sendiri dan belum mengimplementasikan logika untuk membersihkan buffernya sendiri dengan Ctrl +C . Menangguhkan, menabrak, atau membunuh tidak akan begitu baik.
Paksa stdin, stdout, dan stderr agar benar-benar tanpa buffer.