Giriş
Linux komut satırında çalışırken sıkça karşılaşılan stdin, stdout ve stderr terimleri, programların veri alışverişini nasıl gerçekleştirdiğini anlamamız için kritik önem taşır. Bu akışlar, bir komutun kullanıcıdan girdi almasını, çıktısını görüntülemesini ve hataları bildirmesini sağlayan standart kanallardır.
Bu kılavuzda, bu üç standart akışın ne olduğunu, dosya tanımlayıcılarını (0, 1, 2), ve bunların shell tarafından nasıl yönetildiğini detaylı olarak inceleyeceğiz. Ayrıca, çıktı ve hata mesajlarını nasıl ayıracağınızı, akışları dosyalara nasıl yönlendireceğinizi ve pipe (boru) işlemlerinde nasıl kullanacağınızı öğreneceksiniz.
Standart Girdi, Çıktı ve Hata Akışları
Her Linux süreci, çalışmaya başladığında ebeveyninden üç adet açık dosya tanımlayıcısını miras alır. Etkileşimli bir shell üzerinden komut çalıştırdığınızda, bu tanımlayıcılar genellikle aşağıdaki gibi terminale bağlanır:
| Akış | Dosya Tanımlayıcısı | Amacı | Varsayılan Bağlantı |
|---|---|---|---|
stdin |
0 |
Programın okuduğu girdi | Terminalden gelen klavye girişi |
stdout |
1 |
Programın normal çıktısı | Terminal ekranı |
stderr |
2 |
Hata ve tanı mesajları | Terminal ekranı |
Önemli Not: stdin'i basitçe "klavye" olarak tanımlamak yaygın bir kolaylıktır, ancak aslında program bir terminal cihazından okur. Terminal, klavye girişi ve terminal cihazı arasındaki köprü görevi görür. Bir script ya da pipeline içinde stdin, bir dosyadan veya başka bir komuttan da gelebilir.
Dosya Tanımlayıcıları Neden Önemlidir?
Bu sayılar (0, 1, 2), shell'in yönlendirme işlemlerinde bu akışları nasıl tanımladığını belirlediği için önemlidir. Örneğin:
stdout(1) vestderr(2) varsayılan olarak terminale çıktıklarından, ilk bakışta aynıymış gibi görünebilirler. Ancak, ikisi de ayrı akışlardır.- Bir script normal çıktısını bir dosyaya kaydederken, hata mesajlarını başka bir yere gönderebilir.
stdout ve stderr'in Ayrı Görüntülenmesi
Aşağıdaki komutlar, bir normal mesaj ve bir uyarı mesajı üretir:
$ printf "yedek tamamlandı\n"
$ printf "uyarı: arşiv bulunamadı\n" >&2
yedek tamamlandı
uyarı: arşiv bulunamadı
Her iki satır da terminalde görünse de, farklı akışlar üzerinden taşınırlar. İlk printf komutu stdout'a yazar. İkinci komutta ise >&2 yönlendirmesiyle çıktının stderr'a gönderilmesi sağlanır. Bu sayede scriptler, tanı mesajlarını normal verilerden ayırarak rapor edebilirler.
İpucu:
stdoutvestderr'in ayrı dosyalara yönlendirilmesi, özellikle hata ayıklama ve loglama işlemlerinde oldukça faydalıdır. Böylece normal çıktılar ve hatalar ayrı şekilde analiz edilebilir.
Akışların Hedeflerini Değiştirme
Shell, komutu çalıştırmadan önce yönlendirme işlemlerini ayarlar. Program, akışların terminale, dosyaya ya da pipe'a bağlandığını bilmeden, aynı dosya tanımlayıcılarını okumaya ve yazmaya devam eder.
stdout'u Dosyaya Yönlendirme
> operatörü, stdout'u bir dosyaya gönderir ve dosyanın içeriğini yeniden yazar:
$ ls /etc > dosyalar.txt
Bu komut çalıştırıldığında, terminalde hiçbir çıktı görünmez, çünkü dizin listesi dosyalar.txt dosyasına yazılır. > operatörü, tanımlayıcı belirtilmediğinde varsayılan olarak stdout (1) kullanır. Bu nedenle, > dosyalar.txt ve 1> dosyalar.txt aynı etkiye sahiptir.
stderr'i Ayrı Bir Dosyaya Yönlendirme
Varsayılan olarak, stderr terminale bağlı kalır. Aşağıdaki komut, hem mevcut hem de olmayan bir yolu listelemeye çalışır:
$ ls /etc /olmayan_dizin > dosyalar.txt
ls: cannot access '/olmayan_dizin': No such file or directory
Başarılı olan listeleme dosyalar.txt dosyasına kaydedilirken, hata mesajı terminalde görünür çünkü stderr üzerinden iletilir. stderr'i ayırt etmek için tanımlayıcı 2'yi yönlendirin:
$ ls /etc /olmayan_dizin > dosyalar.txt 2> hatalar.txt
Artık normal çıktılar dosyalar.txt'te, hata mesajları ise hatalar.txt'te saklanır.
Uyarı: Yönlendirme ifadeleri soldan sağa doğru işlenir. Örneğin,
command > file 2>&1vecommand 2>&1 > filefarklı sonuçlar üretir. İlk durumda her iki akış dafile'a yazılırken, ikinci durumda sadecestdoutyönlendirilir vestderrterminalde kalır.
Her İki Akışı Tek Bir Dosyaya Yönlendirme
Taşınabilir shell sözdiziminde, hem stdout hem de stderr'i tek bir dosyaya kaydetmek için öncelikle stdout'u yönlendirin, ardından stderr'i aynı hedefe kopyalayın:
$ command > output.log 2>&1
2>&1 ifadesi, dosya tanımlayıcısı 2'nin (stderr), dosya tanımlayıcısı 1'in (stdout) o anki hedefine işaret etmesini sağlar.
Girdiyi Dosyadan Okuma
< operatörü, bir dosyayı stdin'e bağlar. Örneğin, sort komutu, girdisini terminalden değil, bir dosyadan alabilir:
$ sort < isimler.txt
Burada sort, isimler.txt dosyasından okur. Birçok komut dosya adını argüman olarak kabul etse de, girdi yönlendirmesi stdin'den okuma gerektiren komutlar için geçerlidir.
Pipe'ların Akışları Nasıl Kullandığı
Bir pipe (|), bir komutun stdout'unu diğerinin stdin'ine bağlar. Bu sayede veriler geçici bir dosya kullanmadan iki program arasında aktarılabilir:
$ ls /etc | grep conf
Burada ls komutunun stdout çıktısı, grep komutunun stdin girdisine bağlanır. Normal bir pipe sadece stdout'u taşır, stderr'i değil. Bu nedenle ls komutundan kaynaklanan bir hata terminalde görünmeye devam eder ve grep'e geçmez.
İpucu: Hem terminalde gösterirken hem de bir dosyaya kaydetmek için
teekomutunu kullanabilirsiniz:$ ls /etc | tee dosya_listesi.txt | grep conf
Temel Yönlendirme Kuralları
Aşağıda, sık kullanılan yönlendirme işlemlerinin bir özeti yer almaktadır:
| Tanım ya da Sözdizimi | Etkisi |
|---|---|
0 |
stdin |
1 |
stdout |
2 |
stderr |
komut < dosya |
stdin'i dosya'dan okur |
komut > dosya |
stdout'u dosya'ya yazar (içeriği siler) |
komut >> dosya |
stdout'u dosya'ya ekler |
komut 2> dosya |
stderr'u dosya'ya yazar |
komut > dosya 2>&1 |
stdout ve stderr'i aynı dosyaya yazar |
komut 2>/dev/null |
stderr'i yok sayar |
komut1 | komut2 |
komut1'in stdout'unu komut2'nin stdin'ine bağlar |
Sık Karşılaşılan Sorunlar ve Çözümleri
-
Sorun: Bir komut çıktısını beklediğiniz dosyaya kaydetmiyor.
Çözüm: Komutun hangi akışı kullandığını kontrol edin. Örneğin,
ls /etc /olmayan_dizin > dosyalar.txtkomutu sadecestdout'u yönlendirir. Hataları da yakalamak için2> hatalar.txtekleyin. -
Sorun: Bir pipe içinde hata mesajları görünmüyor.
Çözüm: Pipe'lar sadece
stdout'u aktarır. Hata mesajlarını görmek içinstderr'u ayrı bir şekilde yönlendirin ya da2>&1kullanarak her iki akışı da pipe'a dahil edin. -
Sorun: Yönlendirme ifadeleri çalışmıyor.
Çözüm: Yönlendirme kurallarının soldan sağa doğru işlendiğini unutmayın. Örneğin,
komut 2> hatalar.txt > output.txtvekomut > output.txt 2> hatalar.txtfarklı sonuçlar üretir. Hedefi doğru sırayla belirtin.
Sonuç
stdin, stdout ve stderr akışlarını anlamak, Linux komut satırını daha etkili kullanmanızı sağlar. Bu akışlar, programların veri alışverişini nasıl gerçekleştirdiğini ve shell'in bunları nasıl yönettiğini anlamanıza yardımcı olur.
Bir komutun veriyi nereye gönderdiğini anlamak için öncelikle hangi dosya tanımlayıcısını (0, 1 ya da 2) kullandığını tespit edin. Ardından, shell yönlendirme ifadelerini soldan sağa doğru okuyarak hangi hedefe yönlendirildiğini belirleyin. Bu basit adım, shell pipeline'larını ve loglama komutlarını çok daha anlaşılır hale getirecektir.
Artık bu akışları nasıl yöneteceğinizi bildiğinize göre, komut satırında daha verimli ve kontrol edilebilir işlemler gerçekleştirebilirsiniz.

