Saya sudah terbiasa melakukan ini:
someprogram >output.file
Saya melakukannya setiap kali saya ingin menyimpan output yang dihasilkan suatu program ke file. Saya juga mengetahui dua varian pengalihan IO ini :
someprogram 2>output.of.stderr.file
(untuk stderr)someprogram &>output.stderr.and.stdout.file
(untuk kedua stdout + stderr digabungkan)
Hari ini saya telah mengalami situasi yang saya pikir tidak mungkin. Saya menggunakan perintah berikut xinput test 10
dan seperti yang diharapkan, saya memiliki output sebagai berikut:
user @ hostname: ~ $ xinput test 10 tekan tombol 30 pelepasan kunci 30 tekan tombol 40 pelepasan kunci 40 tekan tombol 32 pelepasan kunci 32 tekan tombol 65 pelepasan kunci 65 tekan tombol 61 pelepasan kunci 61 tekan tombol 31 ^ C user @ hostname: ~ $
Saya berharap bahwa output ini seperti biasa dapat disimpan ke file seperti menggunakan xinput test 10 > output.file
. Tetapi ketika bertentangan dengan harapan saya file output.file tetap kosong. Ini juga berlaku untuk xinput test 10 &> output.file
memastikan saya tidak melewatkan sesuatu di stdout atau stderr.
Saya benar-benar bingung dan karenanya bertanya di sini jika xinput
program mungkin memiliki cara untuk menghindari outputnya untuk diarahkan?
memperbarui
Saya telah melihat sumbernya. Tampaknya output dihasilkan oleh kode ini (lihat cuplikan di bawah). Tampaknya bagi saya output akan dihasilkan oleh printf biasa
// dalam file test.c void print_events statis (Tampilan * dpy) { Acara XEvent; sementara (1) { XNextEvent (dpy, & Event); // [... beberapa jenis acara lainnya dihilangkan di sini ...] if ((Event.type == key_press_type) || (Event.type == key_release_type)) { int loop; XDeviceKeyEvent * key = (XDeviceKeyEvent *) & Acara; printf ("key% s% d", (Event.type == key_release_type)? "rilis": "tekan", key-> kode kunci); untuk (loop = 0; loopaxes_count; loop ++) { printf ("a [% d] =% d", key-> first_axis + loop, key-> axis_data [loop]); } printf ("\ n"); } } }
Saya memodifikasi sumber untuk ini (lihat potongan berikutnya di bawah), yang memungkinkan saya untuk memiliki salinan output di stderr. Output ini saya dapat mengarahkan:
// dalam file test.c void print_events statis (Tampilan * dpy) { Acara XEvent; sementara (1) { XNextEvent (dpy, & Event); // [... beberapa jenis acara lainnya dihilangkan di sini ...] if ((Event.type == key_press_type) || (Event.type == key_release_type)) { int loop; XDeviceKeyEvent * key = (XDeviceKeyEvent *) & Acara; printf ("key% s% d", (Event.type == key_release_type)? "rilis": "tekan", key-> kode kunci); fprintf (stderr, "key% s% d", (Event.type == key_release_type)? "rilis": "tekan", key-> keycode); untuk (loop = 0; loopaxes_count; loop ++) { printf ("a [% d] =% d", key-> first_axis + loop, key-> axis_data [loop]); } printf ("\ n"); } } }
Gagasan saya saat ini adalah bahwa mungkin dengan melakukan pengalihan, program kehilangan kemampuannya untuk memantau acara-acara pelepasan kunci.
sumber
setvbuf(stdout, (char *) NULL, _IONBF, NULL)
. Mungkin ini juga menarik !?stdbuf -o0
, sementarastdbug -oL
mengembalikan garis buffering seperti ketika output masuk ke terminal.stdbuf
tidak memaksa aplikasi untuk memanggilsetvbuf
menggunakanLD_PRELOAD
trik.unbuffer test 10 > file
(unbuffer
adalah bagian dariexpect
alat)Sebuah perintah dapat langsung menulis untuk
/dev/tty
mencegah pengalihan rutin terjadi.sumber
/dev/tty
di sistem Linux, gunakanscript -c ./demo demo.log
(dariutil-linux
).Sepertinya
xinput
menolak output ke file tetapi tidak menolak output ke terminal. Untuk mencapai ini, mungkinxinput
gunakan system calluntuk memeriksa apakah skrip yang diajukan dibuka merujuk ke terminal atau tidak.
Saya menemukan fenomena yang sama beberapa waktu lalu dengan sebuah program bernama
dpic
. Setelah saya melihat ke sumber dan beberapa debug saya menghapus baris yang berhubungan denganisatty
dan semuanya berfungsi seperti yang diharapkan lagi.Tapi saya setuju dengan Anda bahwa pengalaman ini sangat mengganggu;)
sumber
isatty
pengujian yang dilakukan. Ouput dihasilkan olehprintf
fungsi (saya pikir ini standar C). Saya menambahkan beberapafprintf(stderr,"output")
dan ini mungkin untuk mengarahkan + membuktikan seluruh kode benar-benar dijalankan dalam kasus xinput. Terima kasih atas sarannya setelah semua itu adalah jejak pertama di sini.Dalam
test.c
file Anda, Anda dapat menyiram data yang disangga menggunakan(void)fflush(stdout);
langsung setelahprintf
pernyataan Anda .Pada baris perintah Anda dapat mengaktifkan output buffer-line dengan menjalankan
xinput test 10
terminal pseudo (pty) denganscript
perintah.sumber
Iya. Saya bahkan melakukan ini dalam DOS-kali ketika saya memprogram dalam pascal. Saya kira prinsipnya masih berlaku:
Ini memang mematahkan pipa.
sumber
con
adalah nama DOS untuk panggilan unix/dev/tty
, yaitu terminal (pengontrol).