---
title: 'Çıkış Kodları'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/cikis-kodlari'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:02+00:00'
license: 'CC BY-SA 4.0'
---

# Çıkış Kodları

Başarı/başarısızlık sözleşmesi, ayrılmış kod aralıkları, koşullu zincirleme işleçleri ve bu işleçlerin koşullu dallanmayla karıştırılmaması.

Önceki derslerde komutların sonuçları hep beklendiği gibi çıktı. Gerçekte `grep` eşleşme
bulamayabilir, `cut` dosyayı açamayabilir, `sort` yeterli geçici alan bulamayabilir.
Kabuğun bu durumları öğrenme yolu tek bir sayıdır.

Her süreç sonlanırken çekirdeğe bir tam sayı bırakır. Kabuk bu sayıyı **çıkış kodu (exit
status)** olarak alır ve `$?` özel değişkeninde saklar. Kabuk programlamanın denetim
akışı — koşullar, döngü koşulları, hata yönetimi — tümüyle bu sayının üzerine kuruludur.

## Sıfır Neden Başarıdır

Sözleşme şudur: **0 başarı, sıfırdan farklı her değer başarısızlıktır.**

Programlama Temelleri kursunda mantıksal doğruluk için `true` değeri kullanılmıştı;
kabuktaki sözleşme bunun tersi görünür. Gerekçe basittir: bir işin başarılı olmasının
tek bir anlamı vardır, başarısız olmasının ise pek çok nedeni. Sıfırdan farklı 255
değer, farklı başarısızlık türlerini ayırt etmek için kullanılabilir; başarı için tek
bir değer yeterlidir.

`grep` bu ayrımın açık bir örneğidir ve üç kodu birbirinden ayırır:

```sh
grep -q '404' erisim.log;      echo "bulundu    -> $?"
grep -q '999' erisim.log;      echo "bulunamadi -> $?"
grep -q '404' yok-dosya.log 2>/dev/null; echo "dosya yok  -> $?"
```

```
bulundu    -> 0
bulunamadi -> 1
dosya yok  -> 2
```

Üçü de birbirinden farklıdır ve bu fark iş görür. "Eşleşme yok" beklenen bir sonuçtur;
"dosya yok" ise betiğin durması gereken bir durumdur. Yalnızca "sıfır mı değil mi" diye
bakan bir betik bu ikisini karıştırır.

Kendi betiklerinizde de aynı titizlik beklenir: farklı hata sınıflarına farklı kodlar
verin, `1` kodunu her şey için kullanmayın.

## Sözleşmeyi Somutlaştıran Komutlar

`true` ve `false` yerleşik komutları hiçbir iş yapmaz; yalnızca kod döndürür.

```sh
true;  echo "true  -> $?"
false; echo "false -> $?"
```

```
true  -> 0
false -> 1
```

`:` komutu `true` ile eşdeğerdir ve önceki derste dosya boşaltmak için kullanılmıştı.

`test` komutu ve onun köşeli ayraç yazımı `[ ... ]` bir koşulu sınar ve sonucu kod olarak
döndürür. Bu komutun hiçbir çıktısı yoktur; tüm bilgi koddadır.

```sh
[ -f erisim.log ]; echo "dosya var -> $?"
[ -f yok.log ];    echo "dosya yok -> $?"
```

```
dosya var -> 0
dosya yok -> 1
```

`[` bir sözdizim öğesi değil, çalıştırılabilir bir komut adıdır; bu yüzden çevresindeki
boşluklar zorunludur ve kapanış `]` onun son argümanıdır. Testlerin ayrıntısı Koşullar ve
Testler dersinde ele alınacak.

## Kodun Sayısal Sınırları

Çıkış kodu 0–255 aralığında bir bayta sığar. Bu aralığın dışındaki değerler 256'ya göre
indirgenir:

```sh
(exit 300); echo "300 -> $?"
(exit -1);  echo "-1  -> $?"
```

```
300 -> 44
-1  -> 255
```

$300 \bmod 256 = 44$ ve $-1 \bmod 256 = 255$. Betiğinizde 255'ten büyük bir kod
döndürmenin anlamı yoktur; sayı sessizce başka bir şeye dönüşür.

## Ayrılmış Kodlar

Kabuk bazı kodları kendi kullanımı için ayırır. Bu kodları kendi hata sınıflarınıza
vermek, betiğinizin çağıranı yanıltmasına yol açar.

```sh
yokboylebirkomut 2>/dev/null; echo "bulunamayan komut  -> $?"
./calismaz.txt   2>/dev/null; echo "calistirilamayan   -> $?"
```

```
bulunamayan komut  -> 127
calistirilamayan   -> 126
```

`127`, komutun arama yolunda bulunamadığını; `126`, bulunduğunu ama çalıştırılamadığını
(çalıştırma izni yok ya da dizin) bildirir. Bir betiği çağırdığınızda 127 alıyorsanız
sorun betiğin içinde değil, adında veya arama yolundadır.

Sinyalle sonlanan süreçler için kabuk **128 + sinyal numarası** biçiminde kod üretir:

```sh
bash -c 'trap - INT; kill -INT $$'; echo "INT  -> $?"
bash -c 'kill -TERM $$';            echo "TERM -> $?"
```

```
INT  -> 130
TERM -> 143
```

`SIGINT` 2 numaralıdır ($128 + 2 = 130$), `SIGTERM` 15 ($128 + 15 = 143$). Klavyeden
kesilen bir betiğin 130 döndürmesinin nedeni budur. Sinyaller ve yakalanmaları Sağlam
Betik Yazımı konusunda ayrıntılı ele alınacak.

Kullanılabilir aralık pratikte 1–125'tir. `exit` komutu argümansız çağrılırsa, betikte
çalışan son komutun kodunu döndürür.

## Koşullu Zincirleme

Kabuk, çıkış koduna bağlı iki zincirleme işleci tanımlar.

`&&` işleci, solundaki komut **0 döndürürse** sağdakini çalıştırır. `||` işleci,
solundaki komut **sıfırdan farklı** döndürürse sağdakini çalıştırır. Her iki durumda da
sağdaki komut çalışmazsa zincirin kodu soldakinin kodudur.

```sh
grep -q '404' erisim.log && echo "kutukte 404 var"
grep -q '999' erisim.log || echo "999 gecmiyor"
```

```
kutukte 404 var
999 gecmiyor
```

Bu işleçler **kısa devre değerlendirme (short-circuit evaluation)** yapar — Programlama
Temelleri kursunda mantıksal işleçler için tanımlanan davranışın aynısıdır. Fark, burada
değerlendirilenin bir ifade değil, çalıştırılan bir süreç olmasıdır: kısa devre yalnızca
zaman kazandırmaz, bir işin hiç yapılmamasını sağlar.

Önceki derste güvenli yerinde dönüştürme deseni bu işleçle yazılmıştı:

```sh
sort kucuk.txt > kucuk.yeni && mv kucuk.yeni kucuk.txt
```

`sort` başarısız olursa `mv` hiç çalışmaz ve özgün dosya yerinde kalır. Yıkıcı işlemi
başarı koşuluna bağlamak, kabukta hata yönetiminin en yalın biçimidir.

## Zincirleme Koşullu Dallanma Değildir

`&&` ve `||` **aynı önceliğe** sahiptir ve **soldan sağa** birleşir. Bu iki kural, sık
görülen bir yanlış anlamayı doğurur: `koşul && gövde || yedek` yazımının `if`–`else`
ile eşdeğer olduğu sanılır. Değildir.

```sh
yanlis() { echo "govde calisti"; return 1; }

true && yanlis || echo "YEDEK CALISTI"
```

```
govde calisti
YEDEK CALISTI
```

Koşul doğruydu, gövde çalıştı — ama gövde başarısızlık bildirdiği için yedek de çalıştı.
`if`–`else` böyle davranmaz:

```sh
if true; then yanlis; else echo "YEDEK"; fi
```

```
govde calisti
```

Kural: **`&&` … `||` zinciri yalnızca gövdenin asla başarısız olmayacağı durumda `if`–`else`
yerine geçer.** Bu güvence nadiren verilebildiği için, iki dallı seçimde `if` yazmak
doğru varsayılandır. `&&` ve `||`, tek dallı korumalar için — "başarılıysa devam et",
"başarısızsa uyar ve çık" — uygundur.

Soldan sağa birleşme, karışık zincirlerde de kendini gösterir:

```sh
false || echo "birinci" && echo "ikinci"
```

```
birinci
ikinci
```

`false || echo "birinci"` önce değerlendirilir; `echo` başarılı olduğu için zincirin kodu
0'dır ve `&&` sağdakini çalıştırır. Okunması güç zincirler yerine gruplama kullanın:
`{ ...; }` içindeki komut listesinin kodu, listenin son komutunun kodudur.

## Değilleme

`!` öneki, bir komutun kodunu tersine çevirir: 0 ise sıfırdan farklı, sıfırdan farklı ise
0 yapar.

```sh
! grep -q '999' erisim.log; echo "degilleme -> $?"
```

```
degilleme -> 0
```

"Kütükte 999 geçmiyorsa" koşulunu ifade etmenin doğrudan yolu budur. Değillemenin ikinci
bir işlevi de vardır: katı kip altında (`set -e`) beklenen başarısızlıkları
bastırmak. Bu kullanım Hata Yönetimi dersinde ele alınacak.

## Konunun Toparlanması

Bu konuda kurulan dört kavram, kursun geri kalanının sözlüğünü oluşturur. Kütükten en çok
istenen beş yolu çıkaran hat, bu sözlüğün tamamını kullanır:

```sh
[ -r erisim.log ] || { echo 'kutuk okunamiyor' >&2; exit 2; }
cut -d' ' -f7 erisim.log | sort | uniq -c | sort -rn | head -5
```

Birinci satır bir çıkış kodu sınaması, bir zincirleme işleci, bir gruplama ve standart
hataya yönlendirme içerir. İkinci satır dört komutluk bir boru hattıdır. İkisi birlikte,
sonraki konuda yazılacak `rapor.sh` betiğinin çekirdeğidir.

## Özet

- Her süreç sonlanırken 0–255 aralığında bir çıkış kodu bırakır; 0 başarı, sıfırdan farklı
  her değer başarısızlıktır. Kod `$?` ile okunur.
- Farklı başarısızlık türleri farklı kodlarla ayrılır; `grep` eşleşmesizlik için 1, dosya
  hatası için 2 döndürür.
- 126, 127 ve 128 + sinyal numarası kabuk tarafından ayrılmıştır; kendi kodlarınız için
  1–125 aralığı kullanılır.
- `&&` ve `||` kısa devre değerlendirme yapar; aynı öncelikte olup soldan sağa birleşir.
- `koşul && gövde || yedek` yazımı, gövdenin başarısız olabildiği durumda `if`–`else` ile
  eşdeğer değildir.

## Sonraki Adım

Bu konudaki her şey tek satırlık komutlarla yapıldı. Aynı hattı her gün çalıştırmak,
üzerine seçenek eklemek ve başkasına devretmek gerektiğinde tek satır yetmez. Sonraki
konu betik dosyasını kurar: yorumlayıcı bildiriminin ne işe yaradığını, betiğin nasıl
çalıştırılabilir hâle geldiğini ve kabuğun bir dosyayı yürütürken hangi kabuğu
kullandığını ele alarak başlar.
