---
title: 'Betik Anatomisi'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/betik-anatomisi'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:01+00:00'
license: 'CC BY-SA 4.0'
---

# Betik Anatomisi

Yorumlayıcı bildirimi, çalıştırma izni, betiği çalıştırmanın üç yolu ve alt süreçle kaynak okuma arasındaki fark.

Önceki konu, komutları akışlarla ve çıkış kodlarıyla birbirine bağlamayı kurdu. Ortaya
çıkan hatlar tek satırlıktı: yazıldıkları anda çalıştılar ve kayboldular. Aynı hattı her
gün çalıştırmak, üzerine seçenek eklemek ve başkasına devretmek gerektiğinde tek satır
yetmez.

**Betik (script)**, kabuğun okuyup sırayla yürüttüğü komutları tutan sıradan bir metin
dosyasıdır. Bu ders dosyanın ne olduğunu, çekirdeğin onu nasıl çalıştırdığını ve üç farklı
çalıştırma yolunun süreç açısından ne anlama geldiğini ele alır.

## İlk Betik

Önceki dersin son hattı bir dosyaya alınır:

```sh
#!/usr/bin/env bash
# rapor.sh — erisim kutugunden ozet rapor uretir.

echo "== En cok istenen yollar =="
cut -d' ' -f7 erisim.log | sort | uniq -c | sort -rn | head -5
```

Bu dosya `rapor.sh` adıyla kaydedilir. Kurs boyunca her konu bu betiği bir adım
ilerletecek; sonunda argüman alan, hataya dayanıklı ve zamanlanmış olarak çalışan bir
araç hâline gelecek.

`#` ile başlayan satırlar **yorumdur**; kabuk onları yok sayar. Yorum işareti satır
başında olmak zorunda değildir ama kelime ortasında yorum başlatmaz:

```sh
echo abc#def
echo abc #def
```

```
abc#def
abc
```

Yorumun başlaması için `#` işaretinin bir kelimenin başında bulunması gerekir. Bu, dosya
adlarında ve URL'lerde `#` geçtiğinde işe yarayan bir kuraldır.

## Çalıştırma İzni

Betik dosyası yaratıldığında çalıştırma izni taşımaz. Doğrudan çağrılırsa:

```sh
./rapor.sh
```

```
bash: ./rapor.sh: Permission denied
```

```sh
echo $?
```

```
126
```

Kod `126`, "dosya bulundu ama çalıştırılamadı" anlamına gelir; önceki derste ayrılmış
kodlar arasında geçmişti. İzin verilir:

```sh
chmod +x rapor.sh
./rapor.sh
```

```
== En cok istenen yollar ==
   6 /api/veri
   4 /yok.html
   4 /index.html
   3 /urun/45
   3 /urun/12
```

Betiğin adının önündeki `./` bırakılırsa sonuç değişir:

```sh
rapor.sh
```

```
bash: rapor.sh: command not found
```

```sh
echo $?
```

```
127
```

Linux'a Giriş kursunun komut yolu dersinde kurulan kural burada işler: eğik çizgi
içermeyen bir ad, yalnızca `PATH` içindeki dizinlerde aranır ve bulunulan dizin bu
listede yer almaz. `./rapor.sh` yazımı adı bir yol hâline getirir ve arama yapılmaz.

Bulunulan dizini `PATH` listesine eklemek yaygın bir öneri değildir: o dizine `ls` adında
bir dosya bırakan herkes, orada çalıştırdığınız her komutu ele geçirebilir.

## Yorumlayıcı Bildirimi

Betiğin ilk satırındaki `#!` dizisi bir yorum gibi görünür ama işlevi kabuğun değil
çekirdeğin ilgi alanındadır. Dosyanın ilk iki baytı `#!` ise, çekirdek onu doğrudan
çalıştırmaya kalkmaz; satırın kalanını bir program yolu olarak okur, o programı başlatır
ve betik dosyasının yolunu ona argüman olarak verir.

Bu düzeneğe **yorumlayıcı bildirimi (shebang)** denir. Üç ayrıntısı vardır.

**Yalnızca ilk satırda geçerlidir.** İkinci satırdaki `#!` sıradan yorumdur. İlk satırın
ilk iki baytı `#!` değilse bildirim yoktur.

**Yol saltıktır, arama yapılmaz.** Çekirdek `PATH` bakmaz. `#!/bin/bash` yazan bir betik,
bash'in `/bin/bash` yolunda bulunmadığı bir sistemde çalışmaz.

**Bildirim yoksa davranış çağırana kalır.** Çekirdek dosyayı çalıştıramaz ve hata
döndürür; bunun üzerine çağıran kabuk çoğu durumda dosyayı kendi alt kabuğuna okutur.
Sonuç, betiği çalıştıran kabuğa bağlıdır — yani taşınabilir değildir.

```sh
printf 'echo "shebangsiz calisti: $0"\n' > yalin.sh
chmod +x yalin.sh
./yalin.sh
```

```
shebangsiz calisti: ./yalin.sh
```

Çalıştı, ama hangi kabukla çalıştığı garanti değildir. Her betiğe yorumlayıcı bildirimi
yazmak zorunlu bir alışkanlıktır.

## Hangi Yorumlayıcı

İki yaygın yazım vardır ve seçim betiğin ne kullandığına bağlıdır.

`#!/bin/sh`, POSIX kabuk dilini bildirir. Bu yolun ucundaki programın hangi kabuk olduğu
sisteme göre değişir; verilen tek güvence, POSIX kabuk dilini yorumlayacağıdır. Dizi,
`[[ ]]`, `<<<`, `${var,,}` gibi bash eklentileri bu bildirimle kullanılamaz — bazı
sistemlerde çalışıyor görünmeleri yanıltıcıdır, çünkü orada `/bin/sh` bash'in POSIX
kipidir.

`#!/usr/bin/env bash`, `env` komutunu çağırarak bash'i `PATH` içinde arar. Bash'in
sistemden sisteme farklı yerlerde kurulu olması bu yazımla soğurulur. Bedeli, `PATH`
üzerinden dolaylı bir arama yapılmasıdır; sabit yol gerektiren sıkı ortamlarda
`#!/bin/bash` yeğlenir.

Karar kuralı: **betikte bash'e özgü tek bir özellik kullanıyorsanız bash bildirin.**
POSIX bildirip bash özelliği kullanmak, betiğin başka bir sistemde sessizce bozulmasının
en sık nedenidir. Bu kursta bash'e özgü her özellik metinde açıkça belirtilecek.

Bash sürümleri arasında da fark vardır. Bir sistemde `/bin/bash` eski bir ana sürüm
olabilir; ilişkisel diziler gibi özellikler orada yoktur. Diziler ve İlişkisel Diziler
dersinde bu farkın ölçülebilir bir örneği verilecek.

## Çalıştırmanın Üç Yolu

Aynı betik üç farklı biçimde yürütülebilir ve üçü aynı şey değildir.

**Doğrudan çalıştırma** (`./rapor.sh`) çalıştırma izni ve yorumlayıcı bildirimi ister.
Yeni bir süreç yaratılır.

**Yorumlayıcıya argüman olarak verme** (`bash rapor.sh`) ne izin ne bildirim ister;
bildirim varsa da yok sayılır, çünkü dosya çalıştırılmaz, okunur. Yine yeni bir süreç
yaratılır.

**Kaynak okuma** (`. rapor.sh` veya `source rapor.sh`) yeni süreç yaratmaz. Komutlar
o anki kabuğun içinde yürütülür.

Üçüncüsünün farkı gözlemlenebilir. `ayar.sh` yalnızca bir değişken atasın:

```sh
KUTUK=erisim.log
```

```sh
bash ayar.sh
echo "alt surec sonrasi: [${KUTUK-tanimsiz}]"
. ./ayar.sh
echo "source sonrasi: [${KUTUK-tanimsiz}]"
```

```
alt surec sonrasi: [tanimsiz]
source sonrasi: [erisim.log]
```

Alt süreçte yapılan atama, süreçle birlikte kayboldu. Boru hattı dersindeki alt kabuk
davranışının aynısıdır: **süreçler arasında değişken geçmez.** Kaynak okuma bu yüzden
yapılandırma dosyaları ve fonksiyon kitaplıkları için kullanılır; iş yapan betikler için
uygun değildir, çünkü betiğin `exit` çağrısı çağıran kabuğu kapatır.

`.` yazımı POSIX'tir, `source` bash eklentisidir; ikisi aynı işi yapar. POSIX yazımında
dosya adı eğik çizgi içermiyorsa `PATH` içinde aranır — `. ./ayar.sh` yazımındaki `./`
bu yüzden gereklidir.

## Betiğin Çıkış Kodu

Bir betik, son çalıştırdığı komutun kodunu döndürür. Aşağıdaki betiğin son satırı
eşleşme bulamayan bir `grep` ise:

```sh
#!/usr/bin/env bash
grep -q '999' erisim.log
```

```sh
./sonkod.sh; echo "kod=$?"
```

```
kod=1
```

Betik başarılı çalıştı ama başarısızlık bildirdi. Bu davranış istenmiyorsa kod açıkça
yazılır: `exit 0`. Çıkış kodunu bilinçli belirlemek, betiği bir zincirde ya da
zamanlanmış görevde kullanılabilir kılan şeydir.

## Çalıştırmadan Sözdizim Denetimi

`bash -n` seçeneği betiği okur, ayrıştırır ama çalıştırmaz. Yarım kalmış bir yapı varsa
bildirir:

```sh
bash -n bozuk.sh
```

```
bozuk.sh: line 4: syntax error: unexpected end of file from `if' command on line 2
```

Bu denetim yalnızca sözdizimini görür; var olmayan komutları, yanlış seçenekleri veya
mantık hatalarını yakalamaz. Yine de yıkıcı işlem içeren bir betiği ilk kez
çalıştırmadan önce yapılacak en ucuz sınamadır. Hata ayıklama araçlarının tamamı Betik
Hata Ayıklama dersinde ele alınacak.

## Özet

- Betik, kabuğun sırayla yürüttüğü komutları tutan metin dosyasıdır; `#` ile başlayan
  kelimeler yorum açar.
- Doğrudan çalıştırma çalıştırma izni ister; izin yoksa kod 126, ad `PATH` içinde
  bulunamazsa 127 döner.
- İlk iki baytı `#!` olan dosyada çekirdek, satırın kalanındaki saltık yolu yorumlayıcı
  olarak başlatır; arama yapmaz ve yalnızca ilk satıra bakar.
- `#!/bin/sh` yalnızca POSIX kabuk dilini güvence altına alır; bash eklentisi kullanan
  betik bash bildirmelidir.
- `bash betik` yeni süreç yaratır, `. betik` yaratmaz; ikincisinde atamalar çağıran
  kabukta kalır.

## Sonraki Adım

Betiğin gövdesindeki kütük adı şimdilik sabit yazılı. Onu bir değişkene almak ilk
bakışta yalnızca düzen meselesi görünür; oysa kabukta değişken genişletmenin sonucu
tırnak kullanımına göre değişir ve tırnaksız bir genişletme, boşluk içeren dosya
adlarında betiği sessizce yanlış çalıştırır. Sonraki ders genişletme, kelime bölme ve
alıntılama kurallarını ele alır.
