---
title: 'Koşullar ve Testler'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/kosullar-ve-testler'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:01+00:00'
license: 'CC BY-SA 4.0'
---

# Koşullar ve Testler

Koşulun bir çıkış kodu olması, dosya/dizgi/sayı testleri, tek ve çift ayraç arasındaki ayrıştırma farkı, kalıp eşleme ve çoklu seçim.

Betik, kendisine verilen kütüğün var olduğunu ve okunabildiğini varsayıyor. Varsayımı
sınamak bir koşul gerektirir. Programlama Temelleri kursunda koşul, mantıksal bir
ifadeydi ve doğru ya da yanlış değerine indirgenirdi.

Kabukta böyle bir tip yoktur. **Koşul, çalıştırılan bir komuttur; sonucu çıkış kodudur.**
`if` yapısı bir ifadeyi değerlendirmez, bir komut çalıştırır ve kodu 0 ise gövdeyi
yürütür. Bu tek fark, kabuk koşullarının tüm sözdizim tuhaflıklarını açıklar.

## `if` Bir Komut Alır

```sh
if komut; then
  ...
elif baska_komut; then
  ...
else
  ...
fi
```

Herhangi bir komut koşul olabilir:

```sh
if grep -q '404' erisim.log; then
  echo "kutukte 404 var"
fi
```

Koşullar için kullanılan `[ ... ]` yazımı bir sözdizim öğesi değil, `test` adlı komutun
ikinci adıdır. Bu yüzden `[` ile ilk argüman arasında boşluk zorunludur ve kapanış `]`
bu komutun son argümanıdır. `[-f dosya]` yazımı `[-f` adında bir komut arar ve
bulunamaz.

## Dosya Testleri

`test`, dosya sistemine ilişkin bir işleçler ailesi tanır.

| İşleç | Doğru olduğu durum |
|---|---|
| `-e` | yol var (türü ne olursa olsun) |
| `-f` | düz dosya |
| `-d` | dizin |
| `-r`, `-w`, `-x` | okuma / yazma / çalıştırma izni var |
| `-s` | dosya var ve boyutu sıfırdan büyük |
| `-L` | sembolik bağ |
| `a -nt b` | `a`, `b`'den daha yeni değiştirilmiş |

```sh
[ -f erisim.log ]; echo "duz dosya  -> $?"
[ -d erisim.log ]; echo "dizin      -> $?"
[ -x erisim.log ]; echo "calistirma -> $?"
```

```
duz dosya  -> 0
dizin      -> 1
calistirma -> 1
```

İzin testleri, dosyanın izin bitlerini değil **çağıran sürecin o dosyada o işlemi yapıp
yapamayacağını** sınar; süper kullanıcı için sonuç farklı çıkabilir. Linux'a Giriş
kursunda kurulan izin modeli burada davranışa dönüşür.

`-e` ile `-f` ayrımı ihmal edilmemelidir: bir dizin de `-e` sınamasını geçer, ama `cut`
ile okunamaz.

## Dizgi ve Sayı Testleri

Dizgi testleri: `-z` boş mu, `-n` boş değil mi, `=` eşit mi, `!=` farklı mı.

Sayı testleri ayrı işleçler kullanır: `-eq`, `-ne`, `-lt`, `-le`, `-gt`, `-ge`.

İki ailenin ayrı olması gereklidir, çünkü kabukta her değer bir karakter dizisidir ve
"eşitlik" iki farklı anlama gelir:

```sh
[ "007" =   "7" ]; echo "dizgi esitligi -> $?"
[ "007" -eq "7" ]; echo "sayi esitligi  -> $?"
```

```
dizgi esitligi -> 1
sayi esitligi  -> 0
```

`007` ile `7` farklı dizgilerdir ama aynı sayıdır. Hangi anlamın istendiğine yazan karar
verir; işleç seçimi bu kararın bildirimidir.

Sayı işleçleri yalnızca tam sayılarla çalışır. Ondalıklı değer verilirse `test` hata
bildirir. Ondalıklı karşılaştırma gerekiyorsa bir hesaplama aracına başvurulur; bu,
Aritmetik ve Komut Yerine Koyma dersinde ele alınacak.

## Tek Ayracın Ayrıştırma Sorunu

`[` sıradan bir komut olduğu için argümanları önce kabuk tarafından genişletilir ve
kelimelere bölünür. Bölme sonucu, `test`'in beklediği argüman sayısını değiştirebilir.

```sh
bos=""
[ $bos = "x" ]
```

```
bash: [: =: unary operator expected
```

Genişletme sonrası `[` komutuna yalnızca `=`, `x`, `]` argümanları ulaştı; `test` bunu
tek işlenenli bir ifade sandı. Aynı sorun boşluk içeren değerde ters yönde çıkar:

```sh
d="iki kelime"
[ $d = "iki kelime" ]
```

```
bash: [: too many arguments
```

Her iki hata da tırnaklamayla giderilir:

```sh
[ "$bos" = "x" ]; echo "kod=$?"
```

```
kod=1
```

Eski betiklerde `[ "x$a" = "xb" ]` biçiminde bir kalıp görülür. Amacı, değişkenin
değerinin bir işleçle karışmasını önlemektir; tırnaklama yeterli olduğu için bu kalıp
artık gereksizdir, ama karşılaşıldığında ne yaptığı bilinmelidir.

## Çift Ayraç

Bash ve ksh, `[[ ... ]]` adında ayrı bir sözdizim öğesi tanır. Bu bir komut değildir;
kabuk onu ayrıştırma aşamasında tanır ve içindeki genişletmelere **kelime bölme ile yol
adı genişletmesi uygulamaz.**

```sh
bos=""; d="iki kelime"
[[ $bos = "x" ]];        echo "bos     -> $?"
[[ $d = "iki kelime" ]]; echo "bosluklu -> $?"
```

```
bos     -> 1
bosluklu -> 0
```

Tırnaksız yazımlar hata vermedi. Bu, `[[ ]]` içinde tırnak gerekmediği anlamına gelir —
ama tırnak yazmak da zarar vermez ve alışkanlığı bozmamak için yeğlenebilir.

Çift ayracın üç ek yeteneği vardır.

**Kalıp eşleme.** `=` veya `==` işlecinin sağ yanı tırnaksızsa yol adı kalıbı olarak
yorumlanır:

```sh
yol="/api/veri"
[[ $yol == /api/* ]]   && echo "api altinda"
[[ $yol == "/api/*" ]] || echo "tirnaklanmis kalip harfi harfine"
```

```
api altinda
tirnaklanmis kalip harfi harfine
```

Sağ yanın tırnaklanması kalıbı sıradan dizgiye çevirir. Bu, kalıp eşlemesinin istenmediği
durumlarda gerekli olan denetimdir.

**Düzenli ifade eşleme.** `=~` işleci sağ yanı genişletilmiş düzenli ifade sayar:

```sh
kod="404"
[[ $kod =~ ^[45][0-9][0-9]$ ]] && echo "hata sinifi kodu"
```

```
hata sinifi kodu
```

Düzenli ifade yazımı Metin İşleme konusunda ayrıntılı ele alınacak. Burada önemli olan,
kalıbın tırnaksız yazılmasıdır: tırnaklanan bir sağ yan harfi harfine eşleşme arar.

**Mantıksal işleçler.** `&&` ve `||`, ayraç içinde koşulları birleştirir:

```sh
[[ -f erisim.log && -r erisim.log ]] && echo "okunabilir dosya"
```

```
okunabilir dosya
```

`[ ]` içinde aynı iş için `-a` ve `-o` işleçleri bulunur, ancak bunlar ayrıştırma
belirsizliği ürettikleri için önerilmez. Taşınabilir yazımda iki ayrı test `&&` ile
zincirlenir:

```sh
[ -f erisim.log ] && [ -r erisim.log ] && echo "okunabilir dosya"
```

**`[[ ]]` bash eklentisidir; POSIX kabuk dilinde yoktur.** `#!/bin/sh` bildiren bir
betikte kullanılamaz. Karar kuralı: bash bildiriliyorsa `[[ ]]` yeğlenir — tırnaklama
hatalarına karşı bağışıktır; POSIX gerekiyorsa `[ ]` ve titiz tırnaklama kullanılır.

## Çoklu Seçim

Aynı değeri birçok olasılığa karşı sınayan `if`–`elif` zincirleri yerine `case` yazılır.
Kalıplar yol adı kalıbı sözdizimini kullanır.

```sh
for k in 200 301 404 500 xyz; do
  case "$k" in
    2??) sinif="basarili" ;;
    3??) sinif="yonlendirme" ;;
    4??) sinif="istemci hatasi" ;;
    5??) sinif="sunucu hatasi" ;;
    *)   sinif="tanimsiz" ;;
  esac
  printf '%-4s -> %s\n' "$k" "$sinif"
done
```

```
200  -> basarili
301  -> yonlendirme
404  -> istemci hatasi
500  -> sunucu hatasi
xyz  -> tanimsiz
```

`case`, ilk eşleşen dalı çalıştırır ve durur; dallar arasında düşme yoktur. Bir kalıba
birden çok seçenek `|` ile eklenir: `200|201|204)`. Son dal olarak yazılan `*)`, hiçbir
kalıba uymayan değerleri yakalar ve her `case` yapısında bulunmalıdır — eksikse tanınmayan
değer sessizce yok sayılır.

`case` POSIX'tir ve `[[ ]]` gerektirmeden kalıp eşleme sağlar; taşınabilir betiklerde
kalıp sınamasının doğru aracıdır.

## Betiğe Uygulama

`rapor.sh` girdilerini sınayacak biçimde genişletilir. Hata sınıflarına ayrı kodlar
verilmesi, önceki dersteki sözleşmenin sürdürülmesidir.

```sh
kutuk="${1:-erisim.log}"

if ! [[ "$adet" =~ ^[0-9]+$ ]] || [ "$adet" -lt 1 ]; then
  echo "hata: -n icin pozitif tam sayi bekleniyor: $adet" >&2
  exit 2
fi

if [ ! -e "$kutuk" ]; then
  echo "hata: kutuk yok: $kutuk" >&2
  exit 3
elif [ ! -f "$kutuk" ]; then
  echo "hata: duz dosya degil: $kutuk" >&2
  exit 3
elif [ ! -r "$kutuk" ]; then
  echo "hata: okuma izni yok: $kutuk" >&2
  exit 3
elif [ ! -s "$kutuk" ]; then
  echo "uyari: kutuk bos: $kutuk" >&2
fi
```

Sayı sınamasında `[ "$adet" -lt 1 ]` testinden önce düzenli ifade sınaması yapılmasının
nedeni sıradır: `adet` sayı değilse `-lt` hata verirdi. `||` kısa devre yaptığı için ikinci
sınamaya yalnızca birincisi geçtiğinde ulaşılır.

Dört çağrı dört yolu izler:

```sh
./rapor.sh yok.log;  echo "kod=$?"
./rapor.sh -n abc;   echo "kod=$?"
./rapor.sh /etc;     echo "kod=$?"
```

```
hata: kutuk yok: yok.log
kod=3
hata: -n icin pozitif tam sayi bekleniyor: abc
kod=2
hata: duz dosya degil: /etc
kod=3
```

## Özet

- Kabukta koşul bir komuttur; `if` çıkış koduna bakar. `[ ]`, `test` komutunun ikinci
  adıdır ve çevresindeki boşluklar zorunludur.
- Dizgi eşitliği `=`, sayı eşitliği `-eq` ile sınanır; `007` ile `7` dizgi olarak farklı,
  sayı olarak aynıdır.
- `[ ]` içindeki genişletmeler kelime bölmeye uğradığı için tırnaklama zorunludur; boş
  veya boşluklu değer aksi hâlde ayrıştırma hatası üretir.
- `[[ ]]` ayrıştırma düzeyinde tanınır, bölme uygulamaz, kalıp ve düzenli ifade eşlemesi
  ile mantıksal işleçler sunar; bash eklentisidir.
- `case` ilk eşleşen dalı çalıştırır, düşme yoktur ve `*)` dalı her zaman yazılmalıdır.

## Sonraki Adım

Rapor şu an tek bir listeyi üretiyor. Durum kodu sınıflarının her biri için ayrı sayım
istendiğinde aynı boru hattını elle çoğaltmak gerekir. Sonraki ders yinelemeyi ele alır:
liste üzerinde dönen döngüler, sayaçlı döngüler ve bir dosyayı satır satır okumanın —
kabukta hiç de apaçık olmayan — doğru biçimi.
