mengirimkan output ke / dev / stderr vs.> & 2

11

Dalam skrip, kesalahan biasanya dikirim ke file deskriptor 2 dengan &2, yaitu:

echo "error" >&2

Kadang /dev/stderr- kadang digunakan sebagai gantinya:

echo "error" > /dev/stderr 

Melihat /dev/stderr, saya melihat bahwa itu hanya sebuah symlink /proc/self/fd/2, yang pada gilirannya adalah symlink ke /dev/pts/5(pada terminal saya saat ini).

Tampak sedikit rumit. Apakah ada logika di balik itu?

Apakah menggunakan /dev/stderrdan &2setara?

Apakah ada yang lebih disukai daripada yang lain?

Martin Vegter
sumber
3
echo "error" >2membuat file dengan nama 2dan konten error.
Cyrus
Saya melihat hasil edit saya diperkenalkan kembali & 2 alih-alih 2. Apakah pertanyaan Anda sebenarnya tentang penggunaan >2, atau >&2?
Jeff Schaller

Jawaban:

13

Perangkat khusus /dev/stderrbersifat khusus sistem, sedangkan deskriptor file 2(bukan perangkat khusus /proc/self/fd/2) bersifat portabel. Jika Anda ingin menulis kode non-portabel, perangkat khusus itu adalah tempat yang baik untuk memulai.

Ada beberapa sistem dengan /dev/stderr: Linux, tentu saja, dan OSX . Tetapi OSX tidak memiliki /procsistem file, dan ini /dev/stderradalah tautan ke /dev/fd/2.

Bacaan lebih lanjut:

Thomas Dickey
sumber
Juga ada kasus di mana seseorang ingin melakukan mis. ini 2> bla.logyang akan berfungsi selama Anda mem-pipe 2dan bukan hard-code /dev/stderr. Pada dasarnya 2tidak perlu berupa stderroutput.
larkey
6

Di bash, dan shell lain, cara untuk mengarahkan sesuatu ke kesalahan standar adalah menggunakan >&2. Bash terbuka /dev/stderrsebagai deskriptor file 2 . Deskriptor file direferensikan oleh di &Nmana Nnomor deskriptor. Jadi, echo error >&2akan mencetak errorke kesalahan standar, ke /dev/stderr.

Itu juga akan terbuka /dev/stdoutsebagai file descriptor 1. Ini artinya Anda bisa melakukannya echo output >&1. Namun, karena semuanya dicetak ke output standar secara default, itu sama echo outputdengan sendirinya.

Sekarang 2>berbeda. Di sini, Anda mengarahkan output kesalahan dari perintah di tempat lain. Jadi, 2>fileberarti "redirect apa pun yang dicetak ke file descriptor 2 (standard error) ke file".

terdon
sumber
3

Anda benar, >&2lebih langsung dan sempurna "idiomatik". Mereka harus setara, jadi tidak ada alasan khusus untuk digunakan >/dev/stderr. Kecuali itu, jika seseorang membaca tidak tahu apa yang dilakukannya, salah satunya mungkin lebih mudah untuk diketahui daripada yang lain :-). Tapi secara umum saya sarankan Anda gunakan >&2.

/ dev / stderr bisa berguna ketika program akan menulis kesalahan ke nama file yang ditentukan, tetapi tidak mendukung stderr. Jelas ini sedikit dibuat-buat; / dev / stdout jauh lebih bermanfaat. (Saya baru-baru ini menemukan mysql_safeskrip wrapper tidak akan menulis kesalahan ke konsol; sayangnya itu juga ingin mengubah izin pada file log kesalahan, jadi menggunakan / dev / stderr menyebabkan beberapa peringatan berlebihan).

sourcejedi
sumber