Apakah ada POSIX, GNU resmi, atau pedoman lain di mana laporan kemajuan dan informasi logging (hal-hal seperti "Melakukan foo; foo dilakukan") harus dicetak? Secara pribadi, saya cenderung menulisnya ke stderr sehingga saya bisa mengarahkan ulang stdout dan hanya mendapatkan output aktual program. Saya baru-baru ini diberitahu bahwa ini bukan praktik yang baik karena laporan kemajuan sebenarnya bukan kesalahan dan hanya pesan kesalahan yang harus dicetak ke stderr.
Kedua posisi tersebut masuk akal, dan tentu saja Anda dapat memilih satu atau yang lain tergantung pada rincian apa yang Anda lakukan, tetapi saya ingin tahu apakah ada standar yang berlaku umum untuk ini. Saya belum dapat menemukan aturan khusus dalam POSIX, standar pengkodean GNU, atau daftar praktik terbaik lainnya yang diterima secara luas.
Kami memiliki beberapa pertanyaan serupa, tetapi mereka tidak membahas masalah yang tepat ini:
Kapan harus menggunakan pengalihan ke stderr dalam skrip shell : Jawaban yang diterima menyarankan apa yang saya cenderung lakukan, menjaga hasil akhir program pada stdout dan apa pun ke stderr. Namun, ini hanya disajikan sebagai pendapat pengguna, meskipun didukung oleh argumen.
Haruskah pesan penggunaan pergi ke stderr atau stdout? : Ini khusus untuk membantu pesan tetapi mengutip standar pengkodean GNU. Ini adalah hal yang saya cari, hanya saja tidak terbatas untuk membantu pesan saja.
Jadi, apakah ada aturan resmi tentang di mana laporan kemajuan dan pesan informatif lainnya (yang bukan bagian dari hasil aktual program) harus dicetak?
stdout
bersama-sama dengan hasilnya adalah cara yang aman untuk membuat hasil tidak berguna. Jika Anda perlu menyalurkan hasilnya ke beberapa program lain, program tersebut perlu memisahkan hasil dari pemintal. Juga, jika Anda mengarahkan output ke file Anda tidak akan dapat melihat pemintal. MENURUT OPINI SAYA.stdout
sebenarnya adalah cara yang aman dan benar untuk melakukan pringting pemintal dan pesan informatif lainnya, tetapi seperti yang dikatakan banyak programmer, 'Diam adalah emas. Tidak menghasilkan apa-apa jika semuanya baik-baik saja. ' jadi pada kenyataannya, stderr selalu digunakan untuk melakukan itu karena definisi yang kabur dan juga stdout dapat memutus urutan pipa. untuk panduan resmistderr
untuk melaporkan pesan kesalahan, kecuali ketika--verbose
bendera digunakan, di mana titik laporan kemajuan disertakan juga.Jawaban:
Posix mendefinisikan stream standar sebagai berikut :
The GNU C Library menggambarkan aliran standar yang sama:
Dengan demikian, definisi standar memiliki sedikit panduan untuk penggunaan aliran di luar "keluaran konvensional / normal" dan "keluaran diagnostik / kesalahan." Dalam praktiknya, biasanya mengarahkan ulang salah satu atau kedua aliran ini ke file dan saluran pipa, di mana indikator kemajuan akan menjadi masalah . Beberapa sistem bahkan memantau
stderr
output dan menganggapnya sebagai tanda masalah. Oleh karena itu, informasi kemajuan yang bersifat tambahan murni bermasalah di kedua aliran.Alih-alih mengirim indikator kemajuan tanpa syarat kepada salah aliran standar, penting untuk mengenali bahwa kemajuan output hanya sesuai untuk interaktif sungai. Dengan mengingat hal itu, saya merekomendasikan penulisan penghitung kemajuan hanya setelah memeriksa apakah aliran itu interaktif (misalnya, dengan
isatty()
) atau ketika diaktifkan secara eksplisit oleh opsi baris perintah. Itu sangat penting untuk pengukur kemajuan yang mengandalkan perilaku pembaruan terminal agar masuk akal, seperti% -complete bar.Untuk pesan kemajuan tertentu yang sangat sederhana ("Memulai X" ... "Selesai dengan X") lebih masuk akal untuk memasukkan output bahkan untuk stream non-interaktif. Dalam hal itu, pertimbangkan bagaimana pengguna dapat berinteraksi dengan stream, seperti mencari dengan
grep
atau paging denganless
atau memantautail -f
. Jika masuk akal untuk melihat pesan kemajuan dalam konteks itu, mereka akan lebih mudah untuk dikonsumsistdout
.sumber
N% done
dan hal-hal sepertidoing foo
danfoo done
. Yang terakhir harus selalu disimpan karena digunakan untuk debugging ketika diarahkan ke file. Jadi saran Anda untuk memeriksa apakah aliran itu interaktif tidak berlaku (meskipun umumnya ide yang sangat bagus).curl
danyum
. Dalam hal ini, saya akan berpikir tentang apakah dan bagaimana pengguna ingin berinteraksi dengan output melaluigrep
atauless
atau alat serupa.POSIX mendefinisikan kesalahan standar sebagai
Ini tidak membatasi penggunaannya untuk pesan kesalahan saja. Saya akan mempertimbangkan informasi kemajuan sebagai hasil diagnostik, jadi itu milik kesalahan standar.
sumber
stdout
adalah buffer-line secara default sedangkanstderr
unbuffered, jadistderr
adalah pilihan alami untuk menulis teks / bar / pemintal kemajuan yang tidak mengandung baris baru. (Jika Anda menulis teks seperti itu padastdout
Anda perlu mengacaukan panggilan output kemajuan Anda denganstdout.flush()
membuatnya terlihat).stdout
, Anda perlu menyiram bahkan jika teks Anda mengandung baris baru jika Anda ingin laporan kemajuan Anda benar-benar muncul secara real time saat diarahkan.POSIX sedikit lebih konkret tentang "informasi diagnostik" di Shell dan Utilities , 1.4: Default Deskripsi Utilitas (penekanan tambang):
IANASL, tetapi saya menafsirkan bahwa itu berarti stderr akan memiliki output hanya jika utilitas akan mengembalikan kode keluar kesalahan. Karena ini seharusnya bukan jalannya peristiwa yang normal untuk eksekusi yang sukses, tidak ada informasi kemajuan yang harus dicetak oleh utilitas POSIX kecuali ada kesalahan (kecuali, tentu saja, ditentukan lain, dll.).
sumber
Dengan prinsip pengecualian, itu hanya bisa pergi ke stderr. Ya, saya tahu Anda bertanya tentang spesifikasi resmi, yang tidak dapat saya tampilkan di luar tautan ke spesifikasi POSIX, yang diberikan oleh Stephen Kitt, yang menyatakan bahwa stderr adalah untuk tujuan diagnostik.
Poin yang lebih penting adalah stdin dan stdout memiliki fungsi yang melarang pencetakan laporan kemajuan menjadi stdout - mereka tentu saja membentuk urutan pipa yang dalam perintah shell Unix bukan hanya efek samping, tetapi inti dari pendekatan perpipaan yang kuat .
Begitu. Tidak ada yang lain kecuali "payload" nyata dari program Anda yang dimiliki stdout. Jika program Anda tidak memiliki output, maka tidak ada yang harus dilakukan untuk stdout. Ini menyisakan stderr untuk yang lainnya , termasuk laporan kemajuan.
Memang, ini meninggalkan lubang - mungkin akan menyenangkan untuk memiliki "stdfluff" atau sesuatu seperti itu yang bukan untuk output atau kesalahan tetapi laporan kemajuan, debugging dan semacamnya. Bahkan, tidak ada yang menghalangi Anda untuk melakukan itu, yaitu, Anda bisa mencetak kemajuan Anda ke file descriptor 3. Contoh:
Ini tidak menghasilkan keluaran. (*)
Ini mencetak ke fd-3, yang diarahkan ke stdout.
(*) Contoh pertama tidak menghasilkan output tetapi masih agak dibuat-buat; yang
open
gagal dan$!
akan mengandungno such file or directory
; ambil saja ini sebagai contoh, tentu saja tidak boleh digunakan seperti ini dengan sungguh-sungguh. Dalam program yang sebenarnya, jika Anda ingin menempuh rute ini, Anda dapat menguji apakah/dev/fd/3
dapat digunakan dan menganggap ini sebagai petunjuk apakah akan mengaktifkan laporan kemajuan Anda; Anda harus melakukannya cukup awal sehingga Anda tidak bingung denganopen
file Anda yang asli dan semacamnya ...sumber
fd-3
? Floppy disk ketiga?Pesan penggunaan harus pergi ke stdout jika pengguna telah memanggilnya dengan
--help
dan ke stderr jika mereka telah melakukan kesalahan. Mencetaknya ke stderr tanpa syarat adalah menjengkelkan karena membuatnya lebih sulit untuk melihatnya dengan pager / grep / etc.Juga, izinkan saya menyarankan cara ketiga: buka / dev / tty untuk laporan kemajuan / pemintal / dll.
sumber
--help
atau membantu pesan sama sekali. Harap baca kembali pertanyaannya.