25 puan yazan GN⁺ 2026-02-28 | 1 yorum | WhatsApp'ta paylaş
  • Standart hata (stderr) ile standart çıktıyı (stdout) tek bir akışta birleştirmek için kullanılan bir yönlendirme sözdizimi
  • 1 sayısı stdout, 2 sayısı stderr anlamına gelir; & ise dosya tanımlayıcısına referans verildiğini gösterir
  • 2>&1, “stderr’i stdout’un o anda yöneldiği yere gönder” anlamına gelir; bu yüzden çıktı sırasına göre sonuç değişebilir
  • Örneğin command >file 2>&1 her iki akışı da dosyaya gönderirken, command 2>&1 >file durumunda yalnızca stderr konsolda kalır
  • Bash ve POSIX shell’lerde çıktı birleştirme, log kaydetme ve pipe işleme için sık kullanılan temel bir yönlendirme sözdizimi

Dosya tanımlayıcıları ve temel kavramlar

  • 0, 1, 2 sırasıyla stdin, stdout, stderr anlamına gelir
    • /usr/include/unistd.h içinde tanımlıdır
    • #define STDIN_FILENO 0, #define STDOUT_FILENO 1, #define STDERR_FILENO 2
  • > çıktı yönlendirmesidir, `` dosyayı yeniden yazar, >> ise dosyaya ekleme yapar
  • & işareti, bir dosya adının değil bir descriptor’ün referans alındığını gösterir
    • Bu nedenle 2>1, çıktıyı adı 1 olan bir dosyaya yönlendirirken; 2>&1, stderr’i stdout’a kopyalar

2>&1 nasıl çalışır?

  • 2> stderr’in yönlendirileceğini, &1 ise stdout’un dosya tanımlayıcısına referans verildiğini ifade eder
  • Sonuç olarak stderr, stdout ile aynı hedefe gider
  • Örnekler:
    • ls -ld /tmp /tnt >/dev/null 2>&1 → her iki çıktı da /dev/null içine atılır
    • ls -ld /tmp /tnt 2>&1 >/dev/null → yalnızca stderr konsolda kalır
  • Yönlendirmeler soldan sağa işlenir, bu nedenle sıra değişirse sonuç da değişir

Yönlendirme sırasının önemi

  • command >file 2>&1
    • Önce stdout dosyaya gider, ardından stderr stdout’a kopyalanır → iki akış da dosyaya gider
  • command 2>&1 >file
    • Önce stderr mevcut stdout’a (konsola) kopyalanır, sonra yalnızca stdout dosyaya gider → stderr hâlâ konsolda görünür
  • Bash, yönlendirmeleri sırayla işler; bu yüzden komut yazarken sıraya dikkat etmek gerekir

Çeşitli yönlendirme örnekleri

  • echo test >file.txt → stdout dosyaya
  • echo test 2>file.txt → stderr dosyaya
  • echo test 1>&2 → stdout stderr’e
  • command &>file veya command >&file → stdout ve stderr birlikte dosyaya (Bash kısayolu)
  • command 2>&1 | tee -a file.txt → iki akışı da aynı anda hem dosyaya hem terminale yazdırır

İleri kullanım ve Bash 4.0 sonrası özellikler

  • Bash 4.0’dan itibaren process substitution kullanılarak çıktılar ayrıştırılabilir
    • ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
    • stdout ve stderr ayrı filtrelere gönderilir
  • |& ifadesi, 2>&1 | için kısaltmadır; iki akışı birleştirip pipe üzerinden iletir
  • set -o noclobber seçeneği mevcut dosyaların üzerine yazmayı engeller; >| ile istisna tanımlanabilir

Pratik kullanım örnekleri

  • g++ main.cpp 2>&1 | head → derleme hataları dahil ilk çıktıları görmeyi sağlar
  • perl test.pl > debug.log 2>&1 → tüm çıktı ve hataları log dosyasına kaydeder
  • foo 2>&1 | grep ERROR → hem stdout hem stderr içinde ERROR arar
  • docker logs container 2>&1 | grep "some log" → tüm log akışını pipe üzerinden geçirir

Kısa özet

  • 2>&1, stderr’i stdout’a kopyalayan POSIX standart sözdizimidir
  • Yönlendirme sırası sonucu belirler; bu yüzden komut yazarken dikkat edilmelidir
  • Bash’te &> ile iki akış birlikte işlenebilir ve bu sözdizimi
    log yönetimi, pipe işleme ve hata birleştirme gibi otomasyon script’lerinde vazgeçilmezdir

1 yorum

 
GN⁺ 2026-02-28
Hacker News yorumları
  • Unix'in syscall API bakış açısından, 2>&1, dup2(1, 2) ile aynı anlama gelir
    Klasik Unix kabuklarında mesele bundan ibarettir, ancak modern kabuklarda durumu izlemek için ek iç bookkeeping bulunur
    redirection işlemi soldan sağa sıralı biçimde yürütülür ve pipe operatörü fork ile dup birleşimiyle çalışır
    Ancak dup2(2, 1) ifadesini 2<1 gibi anlamak sezgisel gelse de, G/Ç anlamı açısından yanlış bir yorumdur

    • iPhone Safari'de “dup2(2, 1)” diye aratınca bu başlık ikinci sırada çıktı
      man7 dup2 belgesi ile Arch Linux dup2 belgesi arasında yer alıyordu
      Botların bunu okuyor olması şaşırtıcı
    • Bu yüzden birçok insanın POSIX kabuk dilini rahatsız edici bulduğunu düşünüyorum
      Fazla miktarda sözdizimsel şeker, alttaki mekanizmayı gizliyor
      Lisp gibi basit bir yapıyı makrolarla genişleten dillerin aksine, kabukta sözdizimi kuralları karmaşık ve sezgisellik zayıf
      Sonuçta programcılarla sistem yöneticileri arasındaki ego çatışması bu tür şikayetleri doğuruyor gibi görünüyor
    • Bu yaklaşımın ilginç bir kullanımı, başlatılmamış dosya tanımlayıcılarını ayarlamaktır
      >&1 echo "stdout"
      >&2 echo "stderr"
      >&3 echo "fd 3"
      ./foo.sh 3>&1 1>/dev/null 2>/dev/null
      
      Böylece yalnızca belirli çıktıları bırakıp geri kalanını susturmak mümkün olur
      Ancak önceden açılmazsa “Bad file descriptor” hatası alınır
    • Kabuk bir program çalıştırırken her zaman fork yapar
      redirection, exec öncesinde dup kullanır; pipe ise iki fork ve pipe syscall'ını kullanır
      BASH kılavuzu gerçekten çok iyi, bu yüzden resmî belgeye bakmak faydalı olur
    • Unix API, C, kabuk ve Perl arasında güçlü bir tutarlılık vardır
      Ama modern dillerde veya Unix dışındaki dillerde bu his kaybolmuştur
  • Sonuçta en güvenilir yol resmî belgeyi (RTFM) doğrudan okumaktır
    Bash Redirections kılavuzu

    • Elbette nerede bakacağını bilen kişi azdır
      Çoğu insan cevabı Google'da arar ve ancak bu tür sorular biriktikçe arama sonuçları oluşur
      Stack Overflow'daki farklı bakış açıları yeni başlayanlar için daha faydalıdır
    • Ama bugünlerde Google araması işe yaramıyor
      Sıradan kullanıcıların istedikleri bilgiyi bulması zor
  • Stack Overflow'daki yanıt benim düşündüğümü aynen ifade ettiği için doğrudan alıntılıyorum
    Bunun &2>&1 değil de 2>&1 olmasının sebebi, & işaretinin yalnızca redirection bağlamında dosya tanımlayıcı anlamına gelmesidir
    PowerShell'in de aynı sözdizimini korumuş olması ilginç

    • PowerShell'de 7 akış vardır: Success, Error, Warning, Verbose, Debug, Information, Progress
      resmî belge bağlantısı
    • Ancak PowerShell sözdizimini ödünç alıp anlambilimi bozuyor
      2>&1 > file sırası Unix'in tersidir, bu yüzden amaçlanan sonuç çıkmaz
      7.4 öncesi sürümlerde bayt akışı bozulması sorunu da vardı
      ilgili belge
    • > işaretinin önündeki sayı, hangi dosya tanımlayıcısının yönlendirileceğini belirtir
      >foo, 1>foo ile aynıdır
      2>>&1 şeklinde yazılırsa 1 adında bir dosya oluşur, dolayısıyla anlamsızdır
    • Aslında kafa karıştırıcı bir şey yok
      > stdout anlamına gelir, 2> stderr anlamına gelir, &1 ise stdout'u ifade eder
    • file1>file2 de simetrik değildir
      /dev/stderr>/dev/stdout daha doğrudan bir karşılıktır
  • Claude'un açıklaması en anlaşılır olanıydı
    2>&1, “hata çıktısını normal çıktının gittiği yere gönder” anlamına gelir

    • 2 hata çıktısıdır, > “gönder” anlamındadır, &1 ise “stdout'un şu anda gittiği yer” demektir
    • Daha doğru söylemek gerekirse 2, dosya tanımlayıcısı 2'dir; > bir atamadır; &1 ise dosya tanımlayıcısı 1'dir
    • Ama bu açıklama aslında zaten Stack Overflow'daki ikinci yanıtla (dbr'nin yanıtı) neredeyse aynıdır
      Bunu LLM'den almak yerine doğrudan bağlantıya tıklamak daha verimlidir
  • İnsanlara soru sorduğumuz Stack Overflow dönemini özlediğimi düşünüyorum
    Ama artık o döneme geri dönmek zor

    • 2025'ten sonra “eski güzel günler” nostaljisi birden büyüdü
      Ama o zamanlarda da gatekeeping ve alaycı bir atmosfer çoktu
      İnsan merkezli işbirliği her zaman romantik değildi
    • Eskiden AI'nın gereksiz uzatmalardan arınmış cevaplarını beğenirdim
      Gereksiz girişler olmadan doğrudan özünü verirdi
    • Soru sormadan önce arama yapmak temel görgü kuralıydı :)
    • “İnsana sormak daha iyidir” sözüne katılmıyorum
      İnsana sormakta ima, yargılanma ve rekabet gibi sosyal yükler vardır
      LLM ise bunlar olmadan nötr ve nazik yanıtlar verir
  • Kabuğun davranışı bağlama bağımlıdır, bu yüzden & işaretinin anlamı konuma göre değişir
    IFS=\| read A B C <<< "first|second|third" örneğinde olduğu gibi, yalnızca tek satır içinde yerel olarak uygulanır
    Satır sonundaki & arka planda çalıştırma anlamına gelirken, ortadaki & redirection anlamına gelir
    Bu tür kalıpları öğrenmek zordur ama sonuçta öğrenilmesi gerekir

  • Kullandığımız sistemlerin ne kadar kadim olduğunu yeniden fark ettim
    Dosya tanımlayıcılarını sayılarla ele almak, kullanıcıya doğrudan işaretçi vermek gibidir
    Keşke ad tabanlı bir yaklaşım mümkün olsaydı

    • Ama o dönemde kullanıcı aynı zamanda programcıydı
    • Hedef tarafında ad kullanılabilir. &, bunun bir dosya değil bir tanımlayıcı olduğunu bildirme işlevi görür
      < zaten girdi yönlendirmesi için kullanılıyordu, bu yüzden yerine geçemezdi
    • Bu kadar basit ve mantıklı araçların onlarca yıl ayakta kalması öğretici
    • 2>/dev/stdout yazımı 2>&1e benzer, ama tam olarak aynı değildir
      /dev/stdout, daha tanıdık ad tabanlı bir erişim biçimidir
    • Ben ise tam tersine bu eski usul kabuk sadeliğini seviyorum
      15 yıl önce yazılmış betikler bugün hâlâ aynen çalışıyor
  • Yönlendirme gerçekten çok ilginç bir özellik
    Örneğin diff <(seq 1 20) <(seq 1 10) gibi process substitution kullanımını sık yapıyorum

    • Ama Unix araçlarının dosya tanımlayıcılarını daha iyi desteklememesi üzücü
      Dosyalar, akışlar ve soketler süreçlere doğrudan aktarılabilse çok daha güçlü olurdu
      Bash içinde bir soketi doğrudan açıp başka bir programa aktarabilsek sandboxing de kolaylaşırdı
      [^1]: /dev/tcp var ama işlevleri sınırlı
    • Ancak “dosya yönlendirmesi” ifadesi biraz yanıltıcı olabilir
      Aslında bu, named pipe ile uygulanır; bu yüzden seek mümkün değildir
      Bu nedenle Zsh'ye geçici dosya kullanan =(command) sözdizimi eklenmiştir
  • Ben 2>&1 ifadesini, “2, 1'in adresine gider” diye ezberleyerek anlamıştım

  • 2>&1 ve redirection konusunu derinlemesine ele alan bir yazı olarak
    Understanding Linux's File Descriptors: A Deep Dive Into '2>&1' and Redirection
    ilgili tartışma bağlantısı

    • Mülakatlarda sık sık O’Reilly'nin Essential System Administration kitabına başvuruyorum
      kitap bağlantısı