Apa itu stdin, stdout, dan stderr di Linux?

Diterbitkan: 2022-01-29
Jendela terminal pada komputer Linux
Fatmawati Achmad Zaenuri/Shutterstock.com

stdin , stdout , dan stderr adalah tiga aliran data yang dibuat saat Anda meluncurkan perintah Linux. Anda dapat menggunakannya untuk mengetahui apakah skrip Anda sedang disalurkan atau dialihkan. Kami tunjukkan caranya.

Aliran Bergabung dengan Dua Poin

Segera setelah Anda mulai belajar tentang Linux dan sistem operasi mirip Unix, Anda akan menemukan istilah stdin , stdout , dan stederr . Ini adalah tiga aliran standar yang dibuat ketika perintah Linux dijalankan. Dalam komputasi, aliran adalah sesuatu yang dapat mentransfer data. Dalam kasus aliran ini, data itu adalah teks.

Aliran data, seperti aliran air, memiliki dua ujung. Mereka memiliki sumber dan arus keluar. Perintah Linux mana pun yang Anda gunakan menyediakan satu ujung dari setiap aliran. Ujung lainnya ditentukan oleh shell yang meluncurkan perintah. Ujung itu akan terhubung ke jendela terminal, terhubung ke pipa, atau diarahkan ke file atau perintah lain, sesuai dengan baris perintah yang meluncurkan perintah.

Aliran Standar Linux

Di Linux, stdin adalah aliran input standar. Ini menerima teks sebagai inputnya. Output teks dari perintah ke shell dikirimkan melalui aliran stdout (standard out). Pesan kesalahan dari perintah dikirim melalui aliran stderr (kesalahan standar).

Jadi Anda dapat melihat bahwa ada dua aliran keluaran, stdout dan stderr , dan satu aliran input, stdin . Karena pesan kesalahan dan keluaran normal masing-masing memiliki saluran sendiri untuk membawanya ke jendela terminal, mereka dapat ditangani secara independen satu sama lain.

Aliran Ditangani Seperti File

Streaming di Linux—seperti hampir semua hal lainnya—diperlakukan seolah-olah itu adalah file. Anda dapat membaca teks dari file, dan Anda dapat menulis teks ke dalam file. Kedua tindakan ini melibatkan aliran data. Jadi konsep menangani aliran data sebagai file tidak terlalu rumit.

Iklan

Setiap file yang terkait dengan suatu proses dialokasikan nomor unik untuk mengidentifikasinya. Ini dikenal sebagai deskriptor file. Setiap kali suatu tindakan diperlukan untuk dilakukan pada file, deskriptor file digunakan untuk mengidentifikasi file.

Nilai-nilai ini selalu digunakan untuk stdin , stdout, dan stderr :

  • 0 : stdin
  • 1 : stdout
  • 2 : stderr

Bereaksi terhadap Pipa dan Pengalihan

Untuk memudahkan pengenalan seseorang terhadap suatu subjek, teknik yang umum adalah mengajarkan versi topik yang disederhanakan. Misalnya, dengan tata bahasa, kita diberitahu bahwa aturannya adalah "I sebelum E, kecuali setelah C." Tapi sebenarnya, ada lebih banyak pengecualian untuk aturan ini daripada kasus yang mematuhinya.

Dalam nada yang sama, ketika berbicara tentang stdin , stdout , dan stderr akan lebih mudah untuk menelusuri aksioma yang diterima bahwa suatu proses tidak mengetahui atau tidak peduli di mana tiga aliran standarnya dihentikan. Haruskah suatu proses peduli apakah outputnya akan ke terminal atau dialihkan ke file? Bisakah ia mengetahui apakah inputnya berasal dari keyboard atau disalurkan ke dalamnya dari proses lain?

Sebenarnya, sebuah proses memang tahu—atau setidaknya bisa mengetahuinya, jika ia memilih untuk memeriksa—dan ia dapat mengubah perilakunya jika pembuat perangkat lunak memutuskan untuk menambahkan fungsionalitas itu.

Iklan

Kita bisa melihat perubahan perilaku ini dengan sangat mudah. Coba dua perintah ini:

 ls 

 ls | kucing 

Perintah ls berperilaku berbeda jika outputnya ( stdout ) sedang disalurkan ke perintah lain. ls yang beralih ke output kolom tunggal, itu bukan konversi yang dilakukan oleh cat . Dan ls melakukan hal yang sama jika outputnya dialihkan:

 ls > capture.txt 

 tangkapan kucing.txt 

Mengarahkan stdout dan stderr

Ada keuntungan memiliki pesan kesalahan yang dikirimkan oleh aliran khusus. Ini berarti kita dapat mengarahkan output perintah ( stdout ) ke file dan masih melihat pesan kesalahan ( stderr ) di jendela terminal. Anda dapat bereaksi terhadap kesalahan jika perlu, saat terjadi. Itu juga menghentikan pesan kesalahan agar tidak mencemari file tempat stdout dialihkan.

Ketik teks berikut ke dalam editor dan simpan ke file bernama error.sh.

 #!/bin/bash

echo "Tentang mencoba mengakses file yang tidak ada"
cat bad-filename.txt

Jadikan skrip dapat dieksekusi dengan perintah ini:

 chmod +x error.sh

Baris pertama skrip menggemakan teks ke jendela terminal, melalui aliran stdout . Baris kedua mencoba mengakses file yang tidak ada. Ini akan menghasilkan pesan kesalahan yang dikirimkan melalui stderr .

Jalankan skrip dengan perintah ini:

 ./error.sh 

Kita dapat melihat bahwa kedua aliran keluaran, stdout dan stderr , telah ditampilkan di jendela terminal.

Mari kita coba mengarahkan output ke file:

 ./error.sh > capture.txt 

Iklan

Pesan kesalahan yang dikirimkan melalui stderr masih dikirim ke jendela terminal. Kita dapat memeriksa isi file untuk melihat apakah output stdout masuk ke file.

 tangkapan kucing.txt 

Output dari stdin dialihkan ke file seperti yang diharapkan.

Simbol pengalihan > bekerja dengan stdout secara default. Anda dapat menggunakan salah satu deskriptor file numerik untuk menunjukkan aliran keluaran standar mana yang ingin Anda arahkan.

Untuk mengarahkan stdout secara eksplisit, gunakan instruksi pengalihan ini:

 1>

Untuk mengarahkan stderr secara eksplisit, gunakan instruksi pengalihan ini:

 2>

Mari kita coba pengujian kita lagi, dan kali ini kita akan menggunakan 2> :

 ./error.sh 2> capture.txt 

Pesan kesalahan dialihkan dan pesan echo stdout dikirim ke jendela terminal:

Mari kita lihat apa yang ada di file capture.txt.

 tangkapan kucing.txt 

Pesan stderr ada di capture.txt seperti yang diharapkan.

Mengarahkan Kedua stdout dan stderr

Tentunya, jika kita dapat mengarahkan stdout atau stderr ke file secara independen satu sama lain, kita harus dapat mengarahkan keduanya pada saat yang sama, ke dua file yang berbeda?

Iklan

Ya kita bisa. Perintah ini akan mengarahkan stdout ke file bernama capture.txt dan stderr ke file bernama error.txt.

 ./error.sh 1> capture.txt 2> error.txt 

Karena kedua aliran keluaran–keluaran standar dan kesalahan standar–dialihkan ke file, tidak ada keluaran yang terlihat di jendela terminal. Kami kembali ke prompt baris perintah seolah-olah tidak ada yang terjadi.

Mari kita periksa isi setiap file:

 tangkapan kucing.txt
 kesalahan kucing.txt 

Mengarahkan stdout dan stderr ke File yang Sama

Itu rapi, kami memiliki masing-masing aliran keluaran standar ke file khusus sendiri. Satu-satunya kombinasi lain yang dapat kita lakukan adalah mengirim stdout dan stderr ke file yang sama.

Kita dapat mencapai ini dengan perintah berikut:

 ./error.sh > capture.txt 2>&1

Mari kita hancurkan itu.

  • ./error.sh : Meluncurkan file skrip error.sh.
  • > capture.txt : Mengarahkan ulang aliran stdout ke file capture.txt. > adalah singkatan dari 1> .
  • 2>&1 : Ini menggunakan instruksi pengalihan &>. Instruksi ini memungkinkan Anda memberi tahu shell untuk membuat satu aliran sampai ke tujuan yang sama dengan aliran lain. Dalam hal ini, kami mengatakan "redirect stream 2, stderr , ke tujuan yang sama dengan stream 1, stdout , sedang diarahkan."

Tidak ada keluaran yang terlihat. Itu menggembirakan.

Mari kita periksa file capture.txt dan lihat apa yang ada di dalamnya.

 tangkapan kucing.txt 

Aliran stdout dan stderr telah dialihkan ke satu file tujuan.

Agar output aliran dialihkan dan dibuang secara diam-diam, arahkan output ke /dev/null .

Mendeteksi Pengalihan Dalam Skrip

Kami membahas bagaimana sebuah perintah dapat mendeteksi jika ada aliran yang dialihkan, dan dapat memilih untuk mengubah perilakunya. Bisakah kita mencapai ini dalam skrip kita sendiri? Ya kita bisa. Dan ini adalah teknik yang sangat mudah untuk dipahami dan digunakan.

Iklan

Ketik teks berikut ke dalam editor dan simpan sebagai input.sh.

 #!/bin/bash

jika [ -t 0 ]; kemudian

  echo stdin berasal dari keyboard
 
kalau tidak

  echo stdin berasal dari pipa atau file
 
fi

Gunakan perintah berikut untuk membuatnya dapat dieksekusi:

 chmod +x input.sh

Bagian yang cerdas adalah ujian di dalam tanda kurung siku. Opsi -t (terminal) mengembalikan nilai true (0) jika file yang terkait dengan deskriptor file berakhir di jendela terminal. Kami telah menggunakan deskriptor file 0 sebagai argumen untuk pengujian, yang mewakili stdin .

Jika stdin terhubung ke jendela terminal, tes akan terbukti benar. Jika stdin terhubung ke file atau pipa, pengujian akan gagal.

Kita dapat menggunakan file teks apa pun yang nyaman untuk menghasilkan input ke skrip. Di sini kita menggunakan yang disebut dummy.txt.

 ./input.sh < dummy.txt 

Outputnya menunjukkan bahwa skrip mengenali bahwa input tidak berasal dari keyboard, itu berasal dari file. Jika Anda memilihnya, Anda dapat memvariasikan perilaku skrip Anda.

Iklan

Itu dengan pengalihan file, mari kita coba dengan pipa.

 boneka kucing.txt | ./input.sh 

Script mengenali bahwa inputnya sedang disalurkan ke dalamnya. Atau lebih tepatnya, ia mengenali sekali lagi bahwa aliran stdin tidak terhubung ke jendela terminal.

Mari jalankan skrip tanpa pipa atau pengalihan.

 ./input.sh 

Aliran stdin terhubung ke jendela terminal, dan skrip melaporkannya.

Untuk memeriksa hal yang sama dengan aliran keluaran, kita memerlukan skrip baru. Ketik yang berikut ini ke dalam editor dan simpan sebagai output.sh.

 #!/bin/bash

jika [ -t 1 ]; kemudian

echo stdout akan pergi ke jendela terminal
 
kalau tidak

echo stdout sedang dialihkan atau disalurkan
 
fi

Gunakan perintah berikut untuk membuatnya dapat dieksekusi:

 chmod +x input.sh

Satu-satunya perubahan signifikan pada skrip ini adalah pada pengujian dalam tanda kurung siku. Kami menggunakan angka 1 untuk mewakili deskriptor file untuk stdout .

Mari kita mencobanya. Kami akan menyalurkan output melalui cat .

 ./keluaran | kucing 

Iklan

Script mengenali bahwa outputnya tidak langsung ke jendela terminal.

Kami juga dapat menguji skrip dengan mengarahkan output ke file.

 ./output.sh > capture.txt 

Tidak ada output ke jendela terminal, kami diam-diam kembali ke command prompt. Seperti yang kita harapkan.

Kita bisa melihat ke dalam file capture.txt untuk melihat apa yang ditangkap. Gunakan perintah berikut untuk melakukannya.

 tangkapan kucing.sh 

Sekali lagi, tes sederhana dalam skrip kami mendeteksi bahwa aliran stdout tidak dikirim langsung ke jendela terminal.

Iklan

Jika kita menjalankan skrip tanpa pipa atau pengalihan, itu akan mendeteksi bahwa stdout sedang dikirim langsung ke jendela terminal.

 ./output.sh 

Dan itulah yang kita lihat.

Aliran Kesadaran

Mengetahui cara mengetahui apakah skrip Anda terhubung ke jendela terminal, atau pipa, atau sedang diarahkan, memungkinkan Anda untuk menyesuaikan perilakunya.

Logging dan keluaran diagnostik dapat lebih atau kurang rinci, tergantung pada apakah itu akan ke layar atau ke file. Pesan kesalahan dapat dicatat ke file yang berbeda dari output program normal.

Seperti biasanya, lebih banyak pengetahuan membawa lebih banyak pilihan.

TERKAIT: Laptop Linux Terbaik untuk Pengembang dan Penggemar