Bir komut satırı uygulaması için 3 temel akış (stream) söz konusu:
0: Giriş için stdin,
1: çıkış için stdout,
2: hata çıktıları için stderr.
Bir uygulamanın konsolda çalıştığı düşünülerek, bazı giriş ve çıkışlarının olduğu varsayılır. stdin olarak isimlendirilen giriş, klavyedir. Program çıktısını stdout'a yani ekrana basar. Olası hata durumlarında ekrana bazı hata mesajları da basılır ama genellikle hata mesajlarının normal stdout çıktısınıdan ayrı olması istendiği için onun akışı ayrıdır, stderr olarak adlandırılır.
stdin yönlendirmesi
Tüm girişin klavyeden değil de, bir programın çıktısından ya da bir dosyadan olması gereken durumlarda kullanılır.
$ head < dosya.txt
Yönlendirme operatörü olarak "<" kullanıldı.
stdout yönlendirmesi
Genelde bir komutun planlanan tüm çıktılarını başka bir komuta veya dosyaya yönlendirmek için kullanılır.
$ ls -ld */ | wc -l # tüm klasörleri say
$ last -s 2019-05-01 | awk '{print $1}' #tarihten sonra yeniden başlatan kullanıcıları isimleri
$ find . -iname "*.txt" -newermt "5 months ago" -ls > new_txt_files.log # son 5 ayda değiştirilen dosyaların listesini new_txt_files.log'a yaz
Burada > operatörünün yanında boru "|" operatörünün de kullanıldığına dikkat.
stderr yönlendirmesi
3 klasörün içeriklerini bir dosyaya yazdığımızı düşünelim. Ama üçüncü klasör var olmayan bir yolu gösteriyor.
$ ls Belgeler Resimler Filmler > dosya_listesi.txt
Bu komut Belgeler ve Resimler klasörünün çıktısını belirtilen dosya_listesi.txt dosyasına yazarken, Filmler klasorunun var olmadığına dair hatayı sadece ekrana yazar ve dosya_listesi.txt dosyasına bir mesaj yazmaz. Bunun sebebi, hata çıktısının farklı bir kanaldan gönderilmesidir. İki seçeneğimiz var. Ya stderr akışını hata.txt dosyası gibi bir dosyaya yazabilir, ya da hataları da dosya_listesi.txt dosyasına atabiliriz. İlk durum için komudumuz şöyle olabilir:
$ ls Belgeler Resimler Filmler 2> hata.txt 1> dosya_listesi.txt
İkinci durum için komudumuz şöyle olabilirdi:
$ ls Belgeler Resimler Filmler > dosya_listesi.txt 2>&1
Burada sonda yer alan 2 numaralı stderr akışını &1'e yönlendirme bölümünün stdout'un dosya_listesi.txt'ye yönlendirmesi (> dosya_listesi.tx) bölümünden sonra olması önemli. Eğer sıra değişirse sadede stdout dosyaya yazılır (çünkü stderr > stdout yönlendirmesi sırasında stdout dosyaya yönlendirilmemiş olur)
Alternatif olarak bash'e özel &> kısaltması (2>&1 ile aynı anlama gelir) kullanılabilir:
$ ls Belgeler Resimler Filmler &> dosya_listesi.txt
---
[1] https://linuxize.com/post/bash-redirect-stderr-stdout/
[2] https://linuxhandbook.com/redirection-linux/
[3] https://www.guru99.com/linux-redirection.html
[4] https://www.putorius.net/linux-io-file-descriptors-and-redirection.html
[5] https://linuxconfig.org/bash-scripting-tutorial-for-beginners