---
title: 'Boru Hattı'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/boru-hatti'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:02+00:00'
license: 'CC BY-SA 4.0'
---

# Boru Hattı

Boru işleci, süreçlerin eşzamanlı çalışması, boru arabelleği ve geri basınç, zincirin çıkış kodu ve alt kabukta kaybolan değişkenler.

Yönlendirme, bir akışın ucuna dosya koyar. Dosya kalıcı bir aracıdır: yazan komut bitmeden
okuyan komut başlayamaz ve ara sonuç diske iner. Oysa çoğu durumda ara sonuç istenmez;
istenen, bir komutun ürettiği metnin doğrudan bir sonrakine geçmesidir.

**Boru hattı (pipeline)** bunu sağlar. Bu ders boru işlecinin ne yaptığını, bu düzenin
neden yalnızca bir yazım kısaltması olmadığını ve getirdiği iki tuzağı ele alır.

## Boru İşleci

`|` işleci, solundaki komutun standart çıktısını sağındakinin standart girdisine bağlar.
Aradaki bağlantı bir dosya değil, çekirdeğin sağladığı **boru (pipe)** adlı bellek içi
tampondur.

Kütükteki istemci adreslerini tekilleştirmek iki komutun bileşimidir:

```sh
cut -d' ' -f1 erisim.log | sort -u
```

```
10.0.0.12
10.0.0.31
10.0.2.7
172.16.0.9
192.168.1.5
```

`cut`, satırları boşluğa göre bölüp birinci alanı yazar; `sort -u` sıralar ve yinelenen
satırları eler. İkisinin arasında hiçbir dosya yaratılmadı.

Zincir uzatılabilir. Aşağıdaki hat, her adresin kaç istek yaptığını çoktan aza doğru
sıralar ve kursun raporlama betiğinin ilk gövdesini oluşturur:

```sh
cut -d' ' -f1 erisim.log | sort | uniq -c | sort -rn
```

```
   7 10.0.0.31
   7 10.0.0.12
   6 10.0.2.7
   5 192.168.1.5
   5 172.16.0.9
```

Aynı hattın yedinci alanla kurulması, istenen yolların dağılımını verir:

```sh
cut -d' ' -f7 erisim.log | sort | uniq -c | sort -rn | head -5
```

```
   6 /api/veri
   4 /yok.html
   4 /index.html
   3 /urun/45
   3 /urun/12
```

Bu dört adımlı desen — **çıkar, sırala, say, sırala** — kabuk metin işlemenin en sık
kullanılan kalıbıdır. `uniq -c` yalnızca **komşu** yinelemeleri saydığı için önündeki
`sort` isteğe bağlı değildir; onsuz sayım yanlış çıkar.

## Süreçler Eşzamanlı Çalışır

Boru hattı, "önce sol biter, sonra sağ başlar" biçiminde çalışmaz. Kabuk hattaki tüm
komutları **aynı anda** başlatır; veri üretildikçe akar.

Bu, gözlemlenebilir bir olgudur. Aşağıdaki hat bir milyon satır üretmeye niyetli bir
komutla başlar ama anında sonuçlanır:

```sh
seq 1 1000000 | head -3
```

```
1
2
3
```

Sıralı çalışsaydı bir milyon satırın tamamı üretilir, sonra ilk üçü alınırdı. Olan şudur:
`head` üç satırı okuduktan sonra çıkar ve borunun okuma ucunu kapatır. Kapalı boruya
yazmaya çalışan `seq`, çekirdekten `SIGPIPE` sinyali alır ve sonlanır.

Eşzamanlılığın iki pratik sonucu vardır. Birincisi, hattın belleği ara sonucun
büyüklüğüyle değil, boru tamponunun sabit boyutuyla sınırlıdır: sınırsız büyüklükte veri
sabit bellekte işlenebilir. İkincisi, sonucun ilk satırları, girdinin tamamı okunmadan
görünmeye başlar.

İkinci sonucun istisnası vardır: `sort` gibi komutlar tanım gereği tüm girdiyi görmeden
tek satır bile yazamaz. Böyle bir komut hattın ortasındaysa akış orada durur ve tamamı
biriktikten sonra devam eder. Hattın belleği de bu noktada girdi büyüklüğüne bağlanır.

## Geri Basınç

Boru tamponunun sabit boyutlu olması, hızlı bir üreticiyle yavaş bir tüketicinin
buluştuğu durumu da çözer. Tampon dolduğunda yazan sürecin yazma çağrısı bloklanır;
okuyan süreç tamponu boşalttıkça yazan devam eder. Bu düzenleme **geri basınç
(backpressure)** olarak adlandırılır.

Sonuç: boru hattında hızlı komut, yavaş komutu asla veriye boğamaz. Bellek tüketimi
zincirin en yavaş halkasına göre değil, tampon boyutuna göre sabittir.

## Zincirin Çıkış Kodu

Bir boru hattının çıkış kodu, öntanımlı olarak **yalnızca son komutun** kodudur. Aradaki
komutların başarısızlığı görünmez olur.

```sh
grep 'YOKBOYLE' erisim.log | sort > /dev/null
echo "durum=$?"
```

```
durum=0
```

`grep` eşleşme bulamadığı için başarısızlık bildirdi, ama hattın kodu `sort`'un kodudur
ve `sort` boş girdiyi sorunsuz sıraladı. Bir betikte bu, sessiz hataların en verimli
kaynağıdır.

Bash iki çözüm sunar. Birincisi `PIPESTATUS` dizisidir; hattaki her komutun kodunu sırayla
tutar:

```sh
grep -c 'YOKBOYLE' erisim.log | wc -l
echo "PIPESTATUS=${PIPESTATUS[*]}"
```

```
       1
PIPESTATUS=1 0
```

İkincisi `pipefail` seçeneğidir. Açıkken hattın kodu, sıfırdan farklı kod döndüren en
sağdaki komutun kodudur:

```sh
set -o pipefail
grep 'YOKBOYLE' erisim.log | sort > /dev/null
echo "pipefail ile durum=$?"
```

```
pipefail ile durum=1
```

`PIPESTATUS` ve `pipefail` bash eklentileridir; POSIX kabuk dilinde tanımlı değildir.
Taşınabilirlik gerekiyorsa ara sonucu geçici dosyaya alıp her adımın kodunu ayrı sınamak
gerekir. Sağlam betik yazımı konusunda `pipefail`, katı kipin sabit parçası olacak.

`pipefail`'in bir yan etkisi vardır: `SIGPIPE` ile sonlanan komutlar da başarısız sayılır.
Yukarıdaki `seq | head` hattı `pipefail` altında sıfırdan farklı kod döndürür. Erken
kesilen hatlarda bu kodun beklenen olduğunu ayrıca ele almak gerekir.

## Alt Kabukta Kaybolan Değişkenler

Boru hattının her bileşeni ayrı bir süreçte çalışır. Kabuğun kendi yerleşik komutları
bile hattın içindeyse **alt kabuk (subshell)** adı verilen bir çocuk süreçte yürütülür.
Alt kabuk, ana kabuğun değişkenlerinin bir kopyasıyla başlar; yaptığı değişiklikler
kendisiyle birlikte yok olur.

```sh
sayac=0
cut -d' ' -f9 erisim.log | while read -r kod; do
  if [ "$kod" = "404" ]; then sayac=$((sayac + 1)); fi
done
echo "boru hatti sonrasi sayac=$sayac"
```

```
boru hatti sonrasi sayac=0
```

Döngü dört kez saydı, ama sayım alt kabukta kaldı. Bu, kabuk betiklerinde en çok zaman
kaybettiren davranışlardan biridir; hata mesajı üretmez, yalnızca yanlış sonuç verir.

Çözüm, döngüyü hattın sağ ucundan çıkarmaktır. Bash'te **süreç yerine koyma (process
substitution)** bir komutun çıktısını dosya gibi gösterir ve döngü ana kabukta kalır:

```sh
sayac=0
while read -r kod; do
  if [ "$kod" = "404" ]; then sayac=$((sayac + 1)); fi
done < <(cut -d' ' -f9 erisim.log)
echo "yeniden yonlendirme ile sayac=$sayac"
```

```
yeniden yonlendirme ile sayac=4
```

`< <(...)` yazımındaki iki karakter dizisi ayrıdır: sağdaki `<(...)` süreç yerine
koymadır, soldaki `<` girdi yönlendirmesidir; aralarındaki boşluk zorunludur. Süreç
yerine koyma da bash eklentisidir. POSIX kabuk dilinde aynı sonuç, sayımı alt kabuktan
metin olarak geri okuyarak elde edilir; bu yol Aritmetik ve Komut Yerine Koyma dersinde
gösterilecek.

Programlama Temelleri kursunda kapsam, adların hangi bölgede görünür olduğu ekseninde
tanımlanmıştı. Kabukta ek bir eksen vardır: adın **hangi süreçte** yaşadığı. İki süreç
arasında değişken geçişi yoktur; yalnızca metin geçişi vardır.

## Hata Akışını Zincire Sokmak

`|` yalnızca standart çıktıyı bağlar. Tanı iletilerinin de bir sonraki komuta gitmesi
isteniyorsa, çoğaltma boru işlecinden **önce** yazılır:

```sh
ls erisim.log yok.txt 2>&1 | sort
```

```
erisim.log
ls: yok.txt: No such file or directory
```

Bash bunun kısaltması olarak `|&` yazımını tanır; POSIX kabuk dilinde bulunmaz.

Bu birleştirme temkinli kullanılmalıdır: veri ile tanı iletisini aynı akışta topladığınız
anda, bir sonraki komut hata metnini de veri sanar. Önceki dersteki kural burada da
geçerlidir — ayrım bilinçli olarak bozulmalıdır, kolaylık olsun diye değil.

## Özet

- Boru işleci, sol komutun standart çıktısını sağ komutun standart girdisine bağlar;
  arada dosya değil, sabit boyutlu bir çekirdek tamponu vardır.
- Hattaki komutlar eşzamanlı çalışır; okuma ucu kapandığında yazan süreç `SIGPIPE` ile
  sonlanır ve gereksiz üretim durur.
- Tampon dolduğunda yazan bloklanır; geri basınç sayesinde bellek tüketimi zincir
  boyunca sabit kalır.
- Hattın öntanımlı çıkış kodu son komutunkidir; ara başarısızlıklar `PIPESTATUS` veya
  `pipefail` ile görünür kılınır.
- Hattın her bileşeni alt kabukta çalıştığı için sağ uçtaki atamalar ana kabuğa geri
  dönmez; döngüyü hattan çıkarmak gerekir.

## Sonraki Adım

Şimdiye kadarki girdiler ya klavyeden ya da var olan bir dosyadan geldi. Betikler
çoğu zaman üçüncü bir kaynağa ihtiyaç duyar: kendi içine gömülü sabit metin —
yapılandırma şablonu, çok satırlı ileti, sınama verisi. Sonraki ders burada belge ve
burada dizgi gösterimlerini ele alır ve bu kursun `erisim.log` dosyasını tek komutla
yeniden üretmenin yolunu gösterir.
