Açık Kaynak İşletim Sistemleri

6 - Standart Girdi Çıktı ve Hata İşlemleri

Emre Can Yılmaz

Ondokuz Mayıs Üniversitesi

2026

Bu Konuyu Neden Görüyoruz?

Komut satırında bir program yalnızca “çalıştırılan bir şey” değildir.
Aynı zamanda veri alır, veri üretir ve hata mesajı da üretebilir.

Bu derste şu sorulara cevap arıyoruz:

  • bir komut veriyi nereden alır?
  • normal çıktıyı nereye yazar?
  • hata mesajı neden bazen dosyaya gitmez?
  • bir komutun çıktısı başka bir komuta nasıl aktarılır?

Bu mantık kurulduğunda yönlendirme ve pipe kullanımı daha anlaşılır hale gelir.

Öğrenme Hedefleri

Bu dersin sonunda şunları yapabiliyor olmanız beklenir:

  • stdin, stdout ve stderr kavramlarını ayırt etmek
  • normal çıktıyı dosyaya yönlendirmek veya dosyanın sonuna eklemek
  • bir dosyayı komuta standart girdi olarak vermek
  • hata mesajlarını ayrı dosyaya almak veya bastırmak
  • komutları | ile bağlayıp küçük boru hatları kurmak
  • 2>&1 ifadesinin ne yaptığını ve neden sıranın önemli olduğunu açıklamak

Temel Fikir

Bir komut çalıştığında ortaya çıkan her şey aynı türde değildir.

Kabuk, üç farklı veri yolunu birbirinden ayrı tutar:

  • standart girdi (stdin) → komutun okuduğu veri
  • standart çıktı (stdout) → komutun ürettiği normal sonuç
  • standart hata (stderr) → komutun ürettiği hata ve uyarı mesajları

Bu ayrımın nedeni şudur:

  • normal çıktıyı bir dosyaya yazmak isteyebiliriz,
  • hata mesajlarını ekranda bırakmak isteyebiliriz,
  • ya da bir komutun çıktısını başka bir komuta aktarmak isteyebiliriz.

Bu yüzden kabuk, girdi, normal çıktı ve hata çıktısını ayrı ayrı yönetir.

Üç Temel Akış

Akış Numara Varsayılan davranış
stdin 0 klavyeden veya başka bir kaynaktan okur
stdout 1 normal çıktıyı terminale yazar
stderr 2 hata mesajlarını terminale yazar

Buradaki 0, 1 ve 2 değerleri dosya tanımlayıcısı olarak düşünülebilir.

Kabuk bu numaraları kullanarak şunu söyleyebilir:

  • 1 numaralı akışı dosyaya gönder
  • 2 numaralı akışı ayrı yerde tut
  • 0 numaralı akışı dosyadan oku

Standart Çıktı (stdout)

Bir komut çalıştırıldığında üretilen normal veri çoğu zaman standart çıktıya yazılır.

$ ls
Belgeler  İndirilenler  Masaüstü  Müzik  Resimler
$ ls -l
total 20
drwxr-xr-x 2 user user 4096 Mar 18 10:00 Belgeler
drwxr-xr-x 2 user user 4096 Mar 18 10:00 İndirilenler
...

Bu iki örnekte de komuta çıktıyı nereye yazacağını açıkça söylemiyoruz. Bu yüzden çıktı varsayılan olarak terminale gelir.

> ile Standart Çıktıyı Dosyaya Yazma

Standart çıktıyı dosyaya yönlendirmek için > kullanırız.

$ ls -l > liste.txt

Bu komuttan sonra çıktı ekranda görünmez. Çünkü normal çıktı artık terminale değil, liste.txt dosyasına yazılmıştır.

Dosyayı kontrol edelim:

$ cat liste.txt
total 20
drwxr-xr-x 2 user user 4096 Mar 18 10:00 Belgeler
drwxr-xr-x 2 user user 4096 Mar 18 10:00 İndirilenler
...

> ve >>

İki benzer ama farklı kullanım vardır:

  • > dosya yoksa oluşturur; varsa içeriği üzerine yazar
  • >> dosyanın sonuna ekleme yapar

Örnek:

$ echo "birinci satir" > notlar.txt
$ echo "ikinci satir" >> notlar.txt
$ cat notlar.txt
birinci satir
ikinci satir

Burada ilk komut dosyayı oluşturur, ikinci komut ise dosyanın sonuna yeni satır ekler.

Standart Girdi (stdin)

Bazı komutlar yalnızca çıktı üretmez; aynı zamanda bir yerden veri de okur.

Bir dosyayı komuta standart girdi olarak vermek için < kullanırız.

$ sort < isimler.txt
$ wc -l < isimler.txt

Bu kullanımda dosya adı, komutun argümanı gibi değil, komutun okuyacağı giriş kaynağı gibi davranır.

< Ne İşe Yarar?

Aşağıdaki iki kullanım benzerdir:

$ wc -l isimler.txt
$ wc -l < isimler.txt

İkisi de satır sayısını verir; fakat aralarında kavramsal fark vardır:

  • ilkinde isimler.txt, komutun argümanıdır
  • ikincisinde isimler.txt, komutun standart girdisi olur

Bu ayrım özellikle pipe ve betik yazarken önem kazanır.

Standart Hata (stderr)

Komutların ürettiği her mesaj normal çıktı değildir.

Kabuk iki tür çıkışı ayrı tutar:

  • stdout → normal veri
  • stderr → hata ve uyarı mesajları

Varsayılan durumda ikisi de terminalde görünür; fakat aynı akış değildirler.

Örnek:

$ ls /olmayan
ls: cannot access '/olmayan': No such file or directory

Buradaki mesaj normal çıktı değil, hata çıktısıdır.

2> ile Hata Çıktısını Ayırma

Hata mesajlarını ayrı dosyaya yönlendirmek için 2> kullanırız.

$ ls /olmayan > normal.txt
ls: cannot access '/olmayan': No such file or directory

Burada normal.txt boş kalır. Çünkü hata mesajı stdout değil, stderr akışındadır.

Şimdi hatayı ayrıca yönlendirelim:

$ ls /olmayan 2> hata.txt
$ cat hata.txt
ls: cannot access '/olmayan': No such file or directory

Buradaki 2, stderr akışının dosya tanımlayıcısını gösterir.

Neden 2> Yazıyoruz?

Az önceki tabloda şunları görmüştük:

  • stdin0
  • stdout1
  • stderr2

Bu yüzden:

  • > dosya aslında çoğu kabukta 1> dosya anlamına gelir
  • 2> dosya ise açıkça hata akışını yönlendirir

Yani kabuğa şunu söylemiş oluruz:

2 numaralı akışı bu dosyaya gönder.

Bu mantık, birazdan göreceğimiz 2>&1 ifadesini de anlaşılır hale getirir.

Hem Normal Çıktı Hem Hata Aynı Yere Gitsin

Bazen hem normal çıktıyı hem de hata mesajlarını aynı dosyada toplamak isteriz.

Bunun için önce stdout yönlendirilir, sonra stderr aynı hedefe bağlanır:

$ ls /etc/passwd /olmayan > sonuc.txt 2>&1
$ cat sonuc.txt
/etc/passwd
ls: cannot access '/olmayan': No such file or directory

Buradaki 2>&1 şu anlama gelir:

  • 2> → hata akışıyla ilgilen
  • &1 → bunu 1 numaralı akışın gittiği yere gönder

Yani stderr, stdout nereye gidiyorsa oraya gider.

2>&1 İfadesini Nasıl Okumalıyız?

Şöyle okuyabilirsiniz:

2 numaralı akışı, 1 numaralı akışın bulunduğu hedefe bağla.

Buradaki fikir “ikisini birleştir” demekten biraz daha özeldir. Aslında olan şudur:

  • önce stdout bir hedefe gider
  • sonra stderr, o hedefe bağlanır

Bu yüzden 2>&1 ifadesi sembolik görünse de mantığı nettir.

Sıra Neden Önemli?

Aşağıdaki iki komut aynı değildir:

$ komut > cikti.txt 2>&1
$ komut 2>&1 > cikti.txt

İlk kullanımda:

  1. stdout dosyaya gider
  2. stderr de stdout nereye gidiyorsa oraya bağlanır Sonuç: ikisi de dosyaya gider

İkinci kullanımda:

  1. stderr, o anda stdout nereye gidiyorsa oraya bağlanır o anda stdout hâlâ terminaldir
  2. sonra stdout dosyaya yönlendirilir Sonuç: stdout dosyaya gider, stderr terminalde kalır

Bu nedenle pratikte en sık kullanılan biçim şudur:

$ komut > dosya 2>&1

Pipe (|) Nedir?

Pipe, bir komutun standart çıktısını başka bir komutun standart girdisine bağlar.

$ ls -l /etc | less

Burada:

  • ls -l /etc çıktı üretir
  • bu çıktı dosyaya gitmez
  • doğrudan less komutuna aktarılır

Bu yapı sayesinde uzun çıktılar ekranda daha rahat incelenir.

Pipe Nasıl Okunur?

Soldan sağa düşünün:

$ grep '/bin/bash' /etc/passwd | wc -l

Burada süreç şöyledir:

  1. grep, eşleşen satırları bulur
  2. bu satırlar stdout ile dışarı çıkar
  3. wc -l, gelen satırları sayar

Bu mantık, daha uzun komut zincirlerinde de aynı şekilde çalışır.

Pipe Yalnızca stdout Taşır

Önemli nokta şudur:

| yalnızca standart çıktıyı taşır.

Hata akışı, ayrıca yönlendirilmedikçe pipe içine girmez.

Örnek:

$ ls /etc/passwd /olmayan | wc -l
ls: cannot access '/olmayan': No such file or directory
1

Burada wc -l, yalnızca normal çıktıyı sayar. Hata mesajı ise terminale ayrı yoldan gelir.

Hatayı da Pipe İçine Katmak

Hata akışını da aynı boru hattına katmak istersek önce stderr ile stdout birleştirilir:

$ ls /etc/passwd /olmayan 2>&1 | wc -l
2

Bu kez iki satır da wc -l tarafından görülür:

  • biri normal çıktı
  • biri hata mesajı

Böylece pipe yalnızca normal veriyi değil, birleştirilmiş akışı işler.

/dev/null

Bazen bir akışı tamamen yok saymak isteriz. Bu amaçla /dev/null kullanılır.

$ komut > /dev/null
$ komut 2> /dev/null
$ komut > /dev/null 2>&1

Yaygın kullanımlar:

  • normal çıktıyı yok saymak
  • hata mesajlarını bastırmak
  • hem çıktıyı hem hatayı görünmez yapmak

Örnek:

$ ls /olmayan 2> /dev/null

Bu komutta hata oluşur; fakat ekranda görünmez.

tee Ne İşe Yarar?

tee, veriyi tek yere değil iki yöne gönderir:

  • ekranda göstermeye devam eder
  • aynı anda bir dosyaya yazar

Örnek:

$ sort isimler.txt | tee sirali.txt | uniq

Burada:

  1. sort veriyi sıralar
  2. tee, bu çıktıyı hem ekranda gösterir hem sirali.txt dosyasına yazar
  3. aynı veri akış üzerinde uniq komutuna da gider

Bu yüzden tee, ara sonucu kaydetmek istediğiniz durumlarda kullanışlıdır.

Kısa Hatırlatma: Sık Kullanılan Kalıplar

$ komut > dosya

Normal çıktıyı dosyaya yazar.

$ komut >> dosya

Normal çıktıyı dosyanın sonuna ekler.

$ komut < dosya

Dosyayı standart girdi olarak verir.

$ komut 2> hata.txt

Hata mesajlarını ayrı dosyaya yazar.

$ komut > hepsi.txt 2>&1

Normal çıktı ve hata aynı dosyaya gider.

$ komut1 | komut2

komut1 çıktısı komut2 girdisi olur.

Çalışma Soruları

  1. /etc dizininin hemen içindeki dosya ve dizinlerin sayısını bulun.
    Yalnızca /etc altında görünen öğeleri sayın; alt dizinlerin içeriğini dahil etmeyin.

  2. emails.txt dosyasındaki tekrar eden satırları ayıklayın ve her satırın yalnızca bir kez geçtiği sonucu benzersiz.txt dosyasına yazın.

  3. Hata mesajı üreten bir komut çalıştırın.
    Bu hata mesajı ekranda görünmesin; yalnızca hata.txt dosyasına yazılsın.

Çalışma Soruları

  1. isimler.txt dosyasındaki satır sayısını iki farklı biçimde bulun:
    önce dosya adını doğrudan komuta vererek, sonra aynı dosyayı standart girdi olarak kullanarak.

  2. /etc/passwd dosyasında /bin/bash ifadesi geçen satırların sayısını bulun.

  3. /etc/passwd dosyasının satırlarını sıralayın.
    Sonucu hem ekranda gösterin hem de aynı anda sirali.txt dosyasına yazın.

Köprü Soru

Aşağıdaki iki komutun farkını açıklayın:

$ ls /etc/passwd /olmayan | wc -l
$ ls /etc/passwd /olmayan 2>&1 | wc -l

Düşünmeniz gereken noktalar:

  • pipe hangi akışı taşır?
  • hata mesajı ilk komutta nereye gider?
  • ikinci komutta neden sonuç değişir?

Bu soru, stderr, 2>&1 ve pipe ilişkisini birlikte düşünmenizi sağlar.

Bonus

/etc/passwd dosyasından kullanıcı adlarını okuyup her kullanıcı için home dizini boyutunu hesaplayan ve sonucu kullanici_boyutlari.txt dosyasına yazan bir çözüm tasarlayın.

Bu soru önceki sorulara göre daha zordur. Tek parça düşünmek yerine adımlara ayırın:

  • kullanıcı adlarını çekme
  • home dizin yollarını belirleme
  • boyut hesaplama
  • sonucu biçimlendirme
  • dosyaya yazma