Kapan menggunakan aliran kesalahan standar dalam aplikasi baris perintah?

9

Apakah ada pedoman kapan harus menggunakan kesalahan saat menulis aplikasi baris perintah? Yang mengejutkan saya, saya tidak menemukan apa pun ketika mencari di Google.

Secara khusus, pertanyaan yang saya khawatirkan saat ini adalah apakah akan menggunakan stdoutatau stderrketika pengguna memanggil program dengan argumen ilegal. Namun, jawaban yang lebih komprehensif sangat dihargai karena ini pasti bukan satu-satunya kasus di mana aturan yang jelas diperlukan untuk menulis sebuah program yang berperilaku seperti yang diharapkan oleh pengguna.

UTF-8
sumber
Apakah tidak apa-apa jika pesan kesalahan itu tercampur dengan output reguler? Misalnya, apakah program filter untuk data?
thrig
Itu bukan filter untuk data. Ini juga tidak interaktif. Pengguna menyebutnya dengan argumen (di antaranya adalah path file), program bekerja, mengubah file-file itu, mencetak beberapa pesan, idealnya tidak mencetak pesan kesalahan apa pun, dan berakhir.
UTF-8

Jawaban:

15

Ya, tampilkan pesan pada stderrsaat argumen yang salah digunakan. Dan jika itu juga menyebabkan aplikasi keluar, keluar dengan status keluar yang tidak nol.

Anda harus menggunakan aliran kesalahan standar untuk pesan diagnostik atau untuk interaksi pengguna. Pesan diagnostik termasuk pesan kesalahan, peringatan, dan pesan lain yang bukan bagian dari keluaran utilitas ketika beroperasi dengan benar ("benar" artinya tidak ada kejadian luar biasa, seperti file yang tidak ditemukan, atau apa pun itu).

Banyak tampilan kerang (semua?) Meminta, apa yang diketik pengguna, dan menu dll. stderrSehingga pengarahan ulang stdouttidak akan menghentikan Anda berinteraksi dengan shell dengan cara yang berarti.

Berikut ini adalah dari posting blog tentang topik ini:

Ini adalah kutipan dari Doug McIllroy, penemu pipa Unix, menjelaskan bagaimana stderrbisa terjadi. 'v6' mengacu pada versi versi spesifik dari sistem operasi Unix asli yang dirilis pada tahun 1975.

Semua program menempatkan diagnostik pada output standar. Ini selalu menyebabkan masalah ketika output diarahkan ke file, tetapi menjadi tidak dapat ditoleransi ketika output dikirim ke proses yang tidak curiga. Namun demikian, karena tidak mau melanggar kesederhanaan model input-standar-output-standar, orang-orang mentolerir keadaan ini melalui v6. Tidak lama kemudian Dennis Ritchie memotong simpul Gordian dengan memperkenalkan file kesalahan standar. Itu tidak cukup. Dengan pipa, diagnostik dapat berasal dari salah satu dari beberapa program yang berjalan secara bersamaan. Diagnostik diperlukan untuk mengidentifikasi diri mereka sendiri.
- Doug McIllroy, "A Research UNIX Reader: Kutipan Beranotasi dari Manual Programmer, 1971-1986"

Untuk "mengidentifikasi diri sendiri" berarti hanya mengatakan "Hei! Ini aku yang berbicara! Ini salah: [...]":

$ ls nothere
ls: nothere: No such file or directory

Melakukan hal ini pada stderrlebih disukai, karena bisa dinyatakan dibaca oleh apa pun yang membaca di stdout(tapi kami tidak melakukannya dengan lstetap , kita?).

Kusalananda
sumber
Jadi ketika Anda menanyakan sesuatu kepada pengguna saat aplikasi sedang berjalan, Anda harus mencetak pertanyaan di stderr? Kedengarannya tidak benar. Apakah Anda punya sumber untuk itu? Apakah ini hanya berlaku untuk aplikasi yang memiliki output selain dari sekadar pertanyaan dan tanggapan (output yang pengguna mungkin ingin pipa di suatu tempat)?
UTF-8
@ UTF-8 Haruskah teks pertanyaan dianggap sebagai bagian dari output program? Bagaimana dengan apa yang diketik pengguna? Saya pikir itu tidak seharusnya (sama seperti kerang tidak berpikir itu seharusnya). Tapi mungkin itu tergantung aplikasinya?
Kusalananda
1
Terima kasih atas hasil edit Anda. Sementara itu, saya memeriksa perilaku aplikasi standar dan mereka berperilaku seperti yang diharapkan mereka berperilaku setelah membaca jawaban Anda.
UTF-8
@ UTF-8 Anda mungkin menemukan Q&A ini relevan: unix.stackexchange.com/q/331611/22222
terdon
5

Dari spesifikasi POSIX untuk stream standar:

Pada awal program, tiga aliran harus ditentukan sebelumnya dan tidak perlu dibuka secara eksplisit: input standar (untuk membaca input konvensional), output standar (untuk penulisan output konvensional), dan standard error (untuk penulisan output diagnostik ).

Dengan kata lain, kesalahan, info debug, dan apa pun yang masuk dalam kategori diagnostik masuk ke dalam stderr.

Lihat pertanyaan terkait untuk info lebih lanjut: Apakah laporan kemajuan / informasi logging milik stderr atau stdout?

Sergiy Kolodyazhnyy
sumber