Akan lebih tepat untuk mengatakan bahwa stdin
, stdout
, dan stderr
adalah "aliran I/O" daripada file. Seperti yang Anda perhatikan, entitas ini tidak hidup di sistem file. Tapi filosofi Unix, sejauh menyangkut I/O, adalah "semuanya adalah file". Dalam praktiknya, itu benar-benar berarti Anda dapat menggunakan fungsi dan antarmuka perpustakaan yang sama (printf
,scanf
, read
, write
, select
, dll.) tanpa mengkhawatirkan apakah aliran I/O terhubung ke keyboard, file disk, soket, pipa, atau abstraksi I/O lainnya.
Sebagian besar program perlu membaca masukan, menulis keluaran, dan mencatat kesalahan, jadi stdin
, stdout
, dan stderr
telah ditentukan sebelumnya untuk Anda, sebagai kenyamanan pemrograman. Ini hanya konvensi, dan tidak diberlakukan oleh sistem operasi.
Saya khawatir pemahaman Anda benar-benar terbalik. :)
Pikirkan "standard in", "standard out", dan "standard error" dari program perspektif, bukan dari perspektif kernel.
Ketika sebuah program perlu mencetak output, biasanya program tersebut mencetak ke "standard out". Suatu program biasanya mencetak output ke standar keluar dengan printf
, yang HANYA mencetak ke standar keluar.
Ketika suatu program perlu mencetak informasi kesalahan (tidak harus pengecualian, itu adalah konstruksi bahasa pemrograman, yang dikenakan pada tingkat yang jauh lebih tinggi), biasanya program itu mencetak ke "kesalahan standar". Biasanya dilakukan dengan fprintf
, yang menerima aliran file untuk digunakan saat mencetak. Aliran file dapat berupa file apa pun yang dibuka untuk penulisan:standar keluar, kesalahan standar, atau file lain apa pun yang telah dibuka dengan fopen
atau fdopen
.
"standard in" digunakan saat file perlu membaca masukan, menggunakan fread
atau fgets
, atau getchar
.
Semua file ini dapat dengan mudah dialihkan dari shell, seperti ini:
cat /etc/passwd > /tmp/out # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err # redirect cat's standard error to /tmp/error
cat < /etc/passwd # redirect cat's standard input to /etc/passwd
Atau, seluruh enchilada:
cat < /etc/passwd > /tmp/out 2> /tmp/err
Ada dua peringatan penting:Pertama, "standard in", "standard out", dan "standard error" hanyalah sebuah konvensi. Mereka sangat kuat konvensi, tetapi itu semua hanya kesepakatan bahwa sangat bagus untuk dapat menjalankan program seperti ini:grep echo /etc/services | awk '{print $2;}' | sort
dan memiliki output standar dari setiap program yang terhubung ke input standar dari program berikutnya dalam alur.
Kedua, saya telah memberikan fungsi ISO C standar untuk bekerja dengan aliran file (FILE *
objek) -- pada level kernel, semuanya adalah deskriptor file (int
referensi ke tabel file) dan banyak operasi tingkat rendah seperti read
dan write
, yang tidak melakukan buffering bahagia dari fungsi ISO C. Saya pikir untuk membuatnya tetap sederhana dan menggunakan fungsi yang lebih mudah, tetapi saya pikir Anda harus mengetahui alternatifnya. :)
Masukan standar - ini adalah pegangan file yang dibaca proses Anda untuk mendapatkan informasi dari Anda.
Keluaran standar - proses Anda menulis keluaran konvensional ke pegangan file ini.
Kesalahan standar - proses Anda menulis hasil diagnostik ke pegangan file ini.
Itu tentang hal bodoh yang saya bisa lakukan :-)
Tentu saja, itu sebagian besar berdasarkan konvensi. Tidak ada yang menghentikan Anda untuk menulis informasi diagnostik ke keluaran standar jika diinginkan. Anda bahkan dapat menutup ketiga pegangan file sepenuhnya dan membuka file Anda sendiri untuk I/O.
Saat proses Anda dimulai, pegangan ini seharusnya sudah terbuka dan dapat dibaca dari dan/atau ditulis ke sana.
Secara default, mereka mungkin terhubung ke perangkat terminal Anda (mis., /dev/tty
) tetapi shell akan memungkinkan Anda untuk mengatur koneksi antara pegangan ini dan file dan/atau perangkat tertentu (atau bahkan menyalurkan ke proses lain) sebelum proses Anda dimulai (beberapa manipulasi yang mungkin dilakukan agak pintar).
Contohnya adalah:
my_prog <inputfile 2>errorfile | grep XYZ
yang akan:
- buat proses untuk
my_prog
. - buka
inputfile
sebagai input standar Anda (pegangan file 0). - buka
errorfile
sebagai kesalahan standar Anda (pegangan file 2). - buat yang lain proses untuk
grep
. - lampirkan keluaran standar
my_prog
ke input standargrep
.
Kembali komentar Anda:
Ketika saya membuka file-file ini di folder /dev, kenapa saya tidak pernah melihat output dari proses yang sedang berjalan?
Itu karena itu bukan file biasa. Sementara UNIX menyajikan semuanya sebagai file dalam sistem file di suatu tempat, itu tidak membuatnya begitu di level terendah. Sebagian besar file dalam /dev
hierarki adalah perangkat karakter atau blok, yang secara efektif merupakan driver perangkat. Mereka tidak memiliki ukuran tetapi memiliki nomor perangkat mayor dan minor.
Saat Anda membukanya, Anda terhubung ke driver perangkat, bukan file fisik, dan driver perangkat cukup pintar untuk mengetahui bahwa proses terpisah harus ditangani secara terpisah.
Hal yang sama berlaku untuk /proc
Linux berkas sistem. Itu bukan file asli, hanya gateway yang dikontrol ketat ke informasi kernel.
Sebagai pelengkap dari jawaban di atas, berikut ringkasan tentang Redirections:
EDIT:Grafik ini tidak sepenuhnya benar.
Contoh pertama tidak menggunakan stdin sama sekali, ini meneruskan "hello" sebagai argumen ke perintah echo.
Grafik juga mengatakan 2>&1 memiliki efek yang sama dengan &> namun
ls Documents ABC > dirlist 2>&1
#does not give the same output as
ls Documents ABC > dirlist &>
Ini karena &> membutuhkan file untuk dialihkan, dan 2>&1 hanya mengirim stderr ke stdout