Kapan harus menggunakan pengalihan ke stderr di skrip shell

15

Saya tahu bahwa utilitas berperilaku baik seperti grep menampilkan pesan "normal" ke stdout, dan pesan kesalahan ke stderr.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Ketika saya sedang menulis skrip shell sendiri, saya sering kesulitan memutuskan output apa dan pesan mana yang harus saya tampilkan di stderr, atau jika saya harus repot-repot sama sekali.

Saya ingin tahu tentang praktik yang baik: Kapan mengarahkan beberapa pesan ke stderr diperlukan dan masuk akal, dan kapan tidak?

"Itu tergantung", tentu, tetapi apakah Anda memiliki wawasan yang akan membantu saya membuat keputusan ini?

Untuk membuat pertanyaan subyektif ini sesuai dengan formatnya, saya ingin mendorong jawaban yang membahas "mengapa", dan diinformasikan oleh pengalaman dan jika mungkin didukung oleh fakta.

glts
sumber
@rush menjelaskannya dengan sempurna. Saya biasanya mencetak laporan kemajuan ke stderr untuk skrip panjang.
terdon

Jawaban:

12

Ketika saya sedang menulis skrip shell sendiri, saya sering kesulitan memutuskan output apa dan pesan mana yang harus saya tampilkan di stderr, atau jika saya harus repot-repot sama sekali.

Diam adalah emas. Tidak menghasilkan apa-apa jika semuanya baik-baik saja.

Saya ingin tahu tentang praktik yang baik: Kapan mengarahkan beberapa pesan ke stderr diperlukan dan masuk akal, dan kapan tidak?

Cara termudah untuk memisahkan stderr dari stdout: bayangkan saja semua hasil skrip Anda akan diarahkan ke perintah lain melalui pipa. Dalam hal ini Anda harus menyimpan semua notifikasi di stderr, karena informasi yang tidak terduga di stdout dapat memutus urutan pipa.

Terkadang juga dalam pipa seperti ini:

command1 | while read line ; do command2 ; done | command3

Anda perlu meneruskan sesuatu dari command2ke hasil pengguna. Cara termudah tanpa file sementara adalah stderr.

buru-buru
sumber
Terima kasih atas gagasan "bayangkan pipa". Kadang-kadang saya menggunakan skrip yang tidak melakukan apa-apa selain "memberi tahu" (echo beberapa variabel, tunjukkan apa yang telah dilakukan, tunjukkan kemajuan). Saya ragu untuk meletakkan semuanya di stderr karena semua ini adalah pesan skrip yang akan dihasilkan. Saya tidak yakin bagaimana menerapkan ide pipa dalam situasi ini.
glts
1
Program @glts selalu dimodifikasi dan ditingkatkan. Meskipun skrip yang Anda sebutkan tidak menghasilkan data apa pun sekarang, skrip tersebut mungkin nanti atau Anda dapat menggunakannya sebagai titik awal untuk skrip lain yang melakukannya. Jika Anda mengikuti konvensi untuk memulai, Anda akan mendapatkan kejutan jauh lebih sedikit nanti. OTOH, jika Anda hanya ingin menyimpan output ke file, maka Anda harus mengarahkan ulang stderr, jadi itu adalah tradeoff seperti yang lainnya.
Joe
+1 Paraphrase lain: pastikan stdout selalu dapat dibaca oleh mesin, atau setidaknya berisi data tekstual yang berguna dalam format yang konsisten.
tripleee
2

Saya biasanya menulis semua yang berhubungan dengan operasi aplikasi stderr, stdoutdicadangkan untuk data.

Bayangkan aplikasi seperti cat. Ketika Anda menggunakannya untuk membaca input dan meneruskannya ke aplikasi lain (melalui pipa), Anda tidak ingin outputnya dikotori dengan pesan status.

Segala sesuatu yang mungkin menarik untuk aplikasi lain atau postprocessor untuk aplikasi saya akan stdout, semua yang hanya berkaitan dengan interna aplikasi saya akan stderr.

Der Hochstapler
sumber
0

Preferensi pribadi saya adalah mengirim pesan kesalahan dan pengecualian ke stderrdan pesan informasi ke stdout. IMO, stderruntuk pengecualian apa pun dan karenanya, konvensi saya.

unxnut
sumber