---
title: 'Özel Değişkenler ve Argümanlar'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/ozel-degiskenler-ve-argumanlar'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:01+00:00'
license: 'CC BY-SA 4.0'
---

# Özel Değişkenler ve Argümanlar

Konumsal parametreler, argüman listesinin iki gösterimi, listeyi tüketen döngü ve seçenek ayrıştırma.

Kütük adı artık bir değişkenden geliyor, ama betiği çağıran için doğal yol bu değildir.
`KUTUK=erisim.log ./rapor.sh` yazmak yerine `./rapor.sh erisim.log` yazmak beklenir.
Komut satırından gelen değerler, kabukta ayrı bir mekanizmayla — **konumsal parametreler
(positional parameters)** ile — karşılanır.

Programlama Temelleri kursunda fonksiyon parametreleri adlarıyla tanımlanıyordu. Kabukta
adlandırma yoktur: parametreler numaralanır ve numaralarıyla okunur. Bu ders o numaraları,
listeyi bir bütün olarak ele almanın iki yolunu ve seçenek ayrıştırmayı kurar.

## Konumsal Parametreler

`$1`, `$2`, … betikçe alınan argümanları sırayla verir. `$0` betiğin çağrıldığı adı,
`$#` argüman sayısını tutar.

```sh
#!/usr/bin/env bash
echo "betik adi     : $0"
echo "arguman sayisi: $#"
echo "ilk           : $1"
echo "ikinci        : $2"
echo "onuncu        : ${10}"
```

```sh
./arg.sh a b c d e f g h i j
```

```
betik adi     : ./arg.sh
arguman sayisi: 10
ilk           : a
ikinci        : b
onuncu        : j
```

Dokuzdan büyük numaralar süslü ayraç ister. `$10` yazılsaydı kabuk bunu `$1` ve `0` diye
okur, ilk argümanın ardına sıfır ekleyerek `a0` üretirdi. Ayraç kullanımı bu yüzden
zorunludur.

`$0`, betiğin çalıştırılırken yazıldığı addır; dosyanın gerçek adı olmak zorunda değildir
ve saltık yol içermeyebilir. Kullanım iletilerinde `$0` yazmak yaygındır ama betiğin
adını sabit yazmak daha okunaklı bir çıktı verir.

## Argüman Listesi: `"$@"` ve `"$*"`

Tüm argümanları birlikte aktarmak için iki gösterim vardır ve aralarındaki fark yalnızca
tırnak içinde ortaya çıkar.

- `"$@"`, her argümanı **ayrı bir kelime** olarak genişletir.
- `"$*"`, tüm argümanları `IFS`'in ilk karakteriyle birleştirip **tek kelime** üretir.
- Tırnaksız `$@` ve `$*`, ikisi de kelime bölmeye uğrar ve ayrım kaybolur.

```sh
#!/usr/bin/env bash
say() { printf 'sayi=%d\n' "$#"; printf '  <%s>\n' "$@"; }
echo '--- "$@" ---'; say "$@"
echo '--- "$*" ---'; say "$*"
echo '--- $@   ---'; say $@
```

```sh
./liste.sh "erisim kutugu.log" 404
```

```
--- "$@" ---
sayi=2
  <erisim kutugu.log>
  <404>
--- "$*" ---
sayi=1
  <erisim kutugu.log 404>
--- $@   ---
sayi=3
  <erisim>
  <kutugu.log>
  <404>
```

Üç sonuç üç farklı anlam taşır. İlki, çağıranın verdiği sınırları koruyarak listeyi
aktarır. İkincisi listeyi tek metne çevirir — ileti yazdırmak dışında bir işe yaramaz.
Üçüncüsü, boşluk içeren argümanı ikiye böler ve çağıranın niyetini bozar.

Kural: **argümanları başka bir komuta aktarırken her zaman `"$@"` kullanın.** Bu, önceki
dersteki tırnaklama kuralının konumsal parametrelere uzanmasıdır.

## Listeyi Tüketmek

`shift` komutu konumsal parametreleri bir sola kaydırır: `$2` yeni `$1` olur, `$#` bir
azalır. Argümanları sırayla işleyen döngülerin temelidir.

```sh
#!/usr/bin/env bash
while [ "$#" -gt 0 ]; do
  echo "islenen: $1 (kalan: $#)"
  shift
done
```

```sh
./shift.sh bir iki uc
```

```
islenen: bir (kalan: 3)
islenen: iki (kalan: 2)
islenen: uc (kalan: 1)
```

`shift N` biçimi bir defada `N` parametre atar. Kalan parametre sayısından fazlasını
atmaya çalışmak sıfırdan farklı kod döndürür ve listeyi değiştirmez.

## Betiğe İlişkin Özel Değişkenler

Kabuk, çalışan betik hakkında birkaç değeri özel adlarda tutar.

| Ad | İçerik |
|---|---|
| `$?` | son komutun çıkış kodu |
| `$$` | çalışan kabuğun süreç numarası |
| `$!` | arka planda başlatılan son sürecin numarası |
| `$-` | etkin kabuk seçenekleri |
| `$0` | betiğin çağrıldığı ad |
| `$#` | konumsal parametre sayısı |

`$$` geçici dosya adı üretmekte sık kullanılır; ancak süreç numaraları yeniden
kullanılabildiği için tek başına güvenli değildir. Tuzaklar ve Temizlik dersinde `mktemp`
ile doğru yol gösterilecek.

`$!` arka plan süreçlerini beklemek ve durdurmak için gerekir; Çıkış Kodları dersinde
sinyal kodları bu değişkenle üretilmişti.

## Seçenek Ayrıştırma

Argümanları elle ayrıştırmak — birinci argüman seçenekse, ikinci onun değeriyse … —
kısa sürede okunmaz hâle gelir. `getopts` yerleşik komutu kısa seçenekleri sözleşmeye
uygun biçimde ayrıştırır.

`getopts` iki argüman alır: tanınan seçeneklerin dizisi ve bulunan seçeneğin yazılacağı
değişken adı. Dizideki bir harfin ardından `:` gelirse o seçenek değer bekler; değer
`OPTARG` değişkenine konur. Dizinin başındaki `:`, hata iletilerini `getopts`'un değil
betiğin üreteceğini bildirir.

```sh
#!/usr/bin/env bash
adet=5
ayrinti=0
while getopts ':n:va' secenek; do
  case "$secenek" in
    n)  adet="$OPTARG" ;;
    v)  ayrinti=1 ;;
    a)  echo "kullanim: sec.sh [-n SAYI] [-v] KUTUK"; exit 0 ;;
    :)  echo "hata: -$OPTARG deger bekliyor" >&2; exit 2 ;;
    \?) echo "hata: bilinmeyen secenek -$OPTARG" >&2; exit 2 ;;
  esac
done
shift $((OPTIND - 1))
echo "adet=$adet ayrinti=$ayrinti kalan=$# ilk=[${1-yok}]"
```

Dört çağrı, dört davranışı gösterir:

```sh
./sec.sh -n 3 -v erisim.log
./sec.sh erisim.log
./sec.sh -n
./sec.sh -z
```

```
adet=3 ayrinti=1 kalan=1 ilk=[erisim.log]
adet=5 ayrinti=0 kalan=1 ilk=[erisim.log]
hata: -n deger bekliyor
hata: bilinmeyen secenek -z
```

Son iki çağrı `2` koduyla sonlandı. Kullanım hatasını başka bir hata sınıfından ayrı bir
kodla bildirmek, betiği zincirde kullanılabilir kılar.

`OPTIND`, `getopts`'un işlediği son argümanın sırasını tutar. Döngüden sonraki
`shift $((OPTIND - 1))` satırı seçenekleri listeden atar; geriye yalnızca seçenek olmayan
argümanlar kalır. Bu satır unutulursa `$1` hâlâ ilk seçeneği gösterir.

`getopts` yalnızca tek harfli seçenekleri tanır; `--ayrinti` gibi uzun seçenekler için
destek yoktur. Uzun seçenek gerekiyorsa `while`–`case` ile elle ayrıştırma yazılır. Ayrıca
`case` dallarındaki `\?` yazımındaki ters bölü gereklidir: `?` `case` kalıplarında tek
karakter eşleyen özel bir simgedir.

## Argüman Sonu İşareti

Tire ile başlayan bir değer, seçenek sanılabilir. Örneğin `-eski.log` adlı bir dosya,
çoğu komut tarafından seçenek olarak yorumlanır. Sözleşme, argüman listesinde `--`
görüldüğünde ondan sonrasının seçenek olmadığını kabul etmektir:

```sh
grep -- '-404-' erisim.log
```

Kendi betiklerinizde de `getopts` bu işareti tanır ve orada durur. Değişkenden gelen
dosya adlarını başka bir komuta aktarırken `--` yazmak, kullanıcı girdisiyle seçenek
karışmasını önler.

## Betiğe Uygulama

`rapor.sh` artık bir arayüz kazanır: kaç satır listeleneceği `-n` ile, kütük adı ilk
konumsal parametreyle verilir.

```sh
#!/usr/bin/env bash
# rapor.sh — erisim kutugunden ozet rapor uretir.
# Kullanim: rapor.sh [-n SAYI] [KUTUK]

adet=5

while getopts ':n:' secenek; do
  case "$secenek" in
    n)  adet="$OPTARG" ;;
    :)  echo "hata: -$OPTARG deger bekliyor" >&2; exit 2 ;;
    \?) echo "hata: bilinmeyen secenek -$OPTARG" >&2; exit 2 ;;
  esac
done
shift $((OPTIND - 1))

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

echo "== Kutuk: $kutuk (ilk $adet yol) =="
cut -d' ' -f7 "$kutuk" | sort | uniq -c | sort -rn | head -"$adet"
```

```sh
./rapor.sh -n 3
```

```
== Kutuk: erisim.log (ilk 3 yol) ==
   6 /api/veri
   4 /yok.html
   4 /index.html
```

Betik hâlâ eksik: verilen kütük yoksa `cut` hata verir ve rapor başlığı boşuna basılmış
olur. Bu eksik sonraki dersin konusudur.

## Özet

- Konumsal parametreler `$1`'den başlar; dokuzdan büyük numaralar süslü ayraç ister.
  `$#` sayıyı, `$0` çağrılan adı verir.
- `"$@"` argümanları ayrı kelimeler olarak, `"$*"` tek kelime olarak genişletir;
  tırnaksız yazımda ikisi de kelime bölmeye uğrar. Aktarımda `"$@"` kullanılır.
- `shift` listeyi bir sola kaydırır ve argümanları sırayla tüketen döngüyü mümkün kılar.
- `getopts` kısa seçenekleri ayrıştırır; `OPTARG` değeri, `OPTIND` işlenen sırayı tutar
  ve döngüden sonra `shift $((OPTIND - 1))` gerekir.
- `--` işareti, ondan sonrasının seçenek olmadığını bildirir ve tire ile başlayan
  değerleri korur.

## Sonraki Adım

Betik, kendisine verilen kütüğün var olduğunu ve okunabildiğini varsayıyor. Bu varsayımı
sınamak için bir koşul gerekir; kabukta koşul, bir komutun çıkış kodudur. Sonraki ders
dosya, dizgi ve sayı testlerini, `[ ]` ile `[[ ]]` arasındaki farkı ve bu farkın neden
sözdizim tercihi değil doğruluk meselesi olduğunu ele alır.
