Bagaimana (dan mengapa) menggunakan stderr untuk membaca dan menulis?


12

Menurut jawaban ini oleh schily , lessmembaca perintah navigasi dari stderr jika itu tidak dapat dibuka /dev/tty.

Ini sepertinya membingungkan, karena saya belum pernah melihat apa pun menulis ke aliran program lain, dan saya tidak tahu bagaimana saya akan mencapai itu.

Apa tujuan stderr terbuka untuk membaca dan menulis? Dan jika ini berguna, bagaimana cara memanfaatkannya pada sistem modern? (Apakah ada beberapa sintaksis misterius untuk menyalurkan sesuatu ke stderr alih-alih stdin, misalnya?)

Jawaban:


7

Awalnya saya terkejut. Namun setelah membaca jawabannya, dan melakukan sedikit penyelidikan, sepertinya sederhana. Jadi inilah yang saya temukan. (pada akhirnya tidak ada kejutan.)

Sebelum pengalihan stdin, stdout, dan stderr seperti yang diharapkan terhubung ke perangkat yang sama.

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

Oleh karena itu setelah sebagian besar arahan ulang (yaitu jika stderr) tidak dialihkan. stderr masih terhubung ke terminal. Karena itu dapat dibaca, untuk mendapatkan input keyboard.

Satu-satunya hal yang menghentikan file yang digunakan dalam arah yang tidak terduga adalah konvensi, dan pipa-pipa itu searah.

Contoh lain, coba:

cat | less

Ini salah setelah halaman, ketika lessmencoba membaca terminal (ini tidak mengherankan, seperti catjuga membaca terminal).

/dev/ttylebih misterius, itu bukan tautan ke /proc/self.

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

Lihat apa hubungan antara terminal pengendali saya saat ini dan `/ dev / tty`? untuk penjelasan. Terima kasih kepada @StephenKitt untuk tautannya.


Mengenai /dev/tty, lihat pertanyaan ini .
Stephen Kitt

6

Ketika Anda masuk, stdin, stdout dan stderr terhubung ke terminal dari tempat Anda masuk. Untuk lebih tepatnya, tty dibuka secara tipikal dan stdout dan stderr adalah hasil dari dua dup(2)operasi pada deskriptor file pertama. Ini memungkinkan untuk membaca dari stderr untuk mendapatkan input dari termnal.

Seperti disebutkan dalam jawaban lain, program membaca dari stderr untuk mendapatkan jawaban interaktif pada sebuah pertanyaan.

Karena pengguna tidak dapat mengetahui dalam keadaan apa suatu program membaca dari stderr, itu adalah upaya yang sia-sia untuk secara sengaja menulis data ke dalam stderr dari program lain.

Perhatikan bahwa program hari ini biasanya pertama-tama mencoba untuk membuka /dev/ttydan menggunakan stderr hanya dalam kasus yang tidak berfungsi.

Program yang hanya membaca dari stderr biasanya belum pernah dimodifikasi sejak sebelum 1979 dan program seperti itu biasanya mengandung konstruksi seperti:

int i 1;

atau

i =* 2;

yang tidak diterima oleh kompiler C modern. Akibatnya, kemungkinan besar hari ini Anda tidak akan menemukan program yang tidak pernah dibuka /dev/ttytetapi membaca balasan interaktif dari stderr.


Jadi jika saya mengerti benar, shell terhubung stderrke tty kapan stdindialihkan (melalui pipa atau cara lain)? Atau hanya selalu terhubung stderrke tty?
Draconis

1
Ketika Anda masuk, stderr terhubung ke terminal login Anda.
schily

2
i =+ 1benar-benar valid C, dan sama dengan i = (+1). Memang, mantan adalah kandidat yang bagus untuk kontes C licik.
G. Sliepen

1
OKE, mungkin itu hanya membuat peringatan. Saya mengubah kode menjadi sesuatu yang lain dari C pada tahun 1977.
schily

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.