Linux'te stdin, stdout ve stderr Nedir? Temel Girdi/Çıktı Akışları ve Yönlendirme

Linux komutlarında stdin, stdout ve stderr'in ne olduğunu, dosya tanımlayıcılarını ve yönlendirme işlemlerini detaylı olarak öğrenin. Girdi/çıktı akışlarını yönetmeyi keşfedin.

I
ITWISE
0 görüntülenme
Linux'te stdin, stdout ve stderr Nedir? Temel Girdi/Çıktı Akışları ve Yönlendirme

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) ve stderr (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: stdout ve stderr'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>&1 ve command 2>&1 > file farklı sonuçlar üretir. İlk durumda her iki akış da file'a yazılırken, ikinci durumda sadece stdout yönlendirilir ve stderr terminalde 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 tee komutunu 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

  1. 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.txt komutu sadece stdout'u yönlendirir. Hataları da yakalamak için 2> hatalar.txt ekleyin.

  2. 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çin stderr'u ayrı bir şekilde yönlendirin ya da 2>&1 kullanarak her iki akışı da pipe'a dahil edin.

  3. 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.txt ve komut > output.txt 2> hatalar.txt farklı 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.

Kaynak

Linuxize