---
title: 'Statik Çözümleme'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/statik-cozumleme'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:00+00:00'
license: 'CC BY-SA 4.0'
---

# Statik Çözümleme

Çalıştırmadan hata bulma, yaygın kabuk hata sınıfları, yorumlayıcı bildirimine göre taşınabilirlik denetimi ve uyarı bastırmanın doğru kullanımı.

Önceki dersin araçları hatayı ortaya çıktıktan sonra bulur. Kabuk betiklerindeki hataların
büyük bölümü ise ortaya çıkmadan önce belirlidir: tırnaklanmamış genişletme, sınanmamış
çıkış kodu, dosya listesini komut çıktısından üretme, yorumlayıcı bildiriminin izin
vermediği bir özelliğin kullanılması.

Bu hatalar kodun kendisine bakılarak, çalıştırılmadan görülebilir. **Statik çözümleme
(static analysis)**, kaynak metni ayrıştırıp bilinen hatalı desenleri arayan yöntemdir.
Kabuk için bu iş, betiği ayrıştırıp yüzlerce desen kuralını uygulayan bir araca devredilir.

Aracın değeri, bu kursta tek tek anlatılan tuzakların hepsini birden hatırlamasıdır.

## Bir Denetim

Aşağıdaki betik, önceki derslerde ele alınan hataların çoğunu bir arada taşıyor:

```sh
#!/bin/sh
kutuk=$1
for f in $(ls kutukler); do
  echo "islenen: $f"
done
if [ $kutuk = "erisim.log" ]; then
  adet=`wc -l < $kutuk`
  echo "satir: $adet"
fi
cd /tmp
rm -rf $kutuk_yedek
```

Çözümleyicinin uzun biçimli çıktısı, bulguyu kaynak satırın altında işaretler ve
düzeltilmiş yazımı önerir. Aynı bulgular tek satırlık biçimde daha derli toplu okunur:

```sh
shellcheck -f gcc kusurlu.sh
```

```
kusurlu.sh:3:10: error: Iterating over ls output is fragile. Use globs. [SC2045]
kusurlu.sh:6:6: note: Double quote to prevent globbing and word splitting. [SC2086]
kusurlu.sh:7:8: note: Use $(...) notation instead of legacy backticks `...`. [SC2006]
kusurlu.sh:7:17: note: Double quote to prevent globbing and word splitting. [SC2086]
kusurlu.sh:10:1: warning: Use 'cd ... || exit' or 'cd ... || return' in case cd fails. [SC2164]
kusurlu.sh:11:8: warning: kutuk_yedek is referenced but not assigned. [SC2154]
```

Beş ayrı hata sınıfı, on bir satırlık bir betikte. Sonuncusunun sonucu, `set -u` olmayan
bir betikte `rm -rf` komutunun argümansız çalışmasıdır.

Öntanımlı biçim daha ayrıntılıdır: her bulgunun altına `Did you mean:` başlığıyla
düzeltilmiş satırı yazar. Tek bir bulguyla uğraşırken bu biçim, toplu denetimde ise
yukarıdaki tek satırlık biçim uygundur.

## Yakalanan Hata Sınıfları

Uyarılar dört öbeğe ayrılır ve her biri bu kursta ayrı bir dersin konusuydu.

**Genişletme ve tırnaklama.** Tırnaklanmamış değişken genişletmesi, `"$@"` yerine `$*`
kullanımı, dizi genişletmesinin yanlış biçimi. Değişkenler ve Tırnak Kuralları dersinin
tamamı bu sınıfa aittir. En sık görülen uyarı budur.

**Çıkış kodu.** Sınanmayan `cd`, sınanmayan komut yerine koyma, `local` ile birlikte atama
yapılması, boru hattı kodunun kaybolması. Hata Yönetimi dersindeki tuzaklar burada
yakalanır.

**Kabuk deyimleri.** Dosya listesini komut çıktısından üretme, `read` çağrısında `-r`
eksikliği, eski ters tırnak yazımı, `[ ]` içinde yanlış işleç. Döngüler ve Koşullar
derslerinin uyarıları.

**Tanımsız ad.** Hiç atanmamış bir değişkenin okunması, yazım yanlışıyla farklı bir ada
dönüşen değişkenler. Bu sınıf, yorumlanan bir dilde çalışma anında bile fark edilmeyebilir.

Her uyarının bir kimliği vardır (`SC` ve dört rakam). Kimlik iki işe yarar: uyarının
ayrıntılı açıklamasına ulaşmak ve — gerektiğinde — o uyarıyı hedefli biçimde bastırmak.

## Şiddet Düzeyleri

Uyarılar dört düzeye ayrılır: `error`, `warning`, `info`, `style`. `-S` seçeneği belirli
bir düzeyin altındakileri gizler:

```sh
shellcheck -S warning -f gcc kusurlu.sh
```

```
kusurlu.sh:3:10: error: Iterating over ls output is fragile. Use globs. [SC2045]
kusurlu.sh:10:1: warning: Use 'cd ... || exit' or 'cd ... || return' in case cd fails. [SC2164]
kusurlu.sh:11:8: warning: kutuk_yedek is referenced but not assigned. [SC2154]
```

Üç bulgu kaldı; `info` ve `style` düzeyindeki tırnaklama ve ters tırnak uyarıları
gizlendi.

Bu, var olan bir kod tabanına çözümleme eklerken yararlıdır: önce `error` düzeyi
temizlenir, sonra eşik kademeli olarak düşürülür. Eşiği kalıcı olarak yüksek tutmak ise
aracın değerinin çoğunu bırakmak demektir — `info` düzeyindeki tırnaklama uyarıları en sık
gerçek hataya dönüşenlerdir.

## Taşınabilirlik Denetimi

Çözümleyici, yorumlayıcı bildirimini okur ve kuralları ona göre uygular. `#!/bin/sh`
bildiren bir betikte bash eklentileri hata sayılır:

```sh
#!/bin/sh
kodlar=(200 404)
if [[ ${#kodlar[@]} -gt 1 ]]; then
  echo "birden cok kod"
fi
```

```
In tasinabilir.sh line 2:
kodlar=(200 404)
       ^-------^ SC3030 (warning): In POSIX sh, arrays are undefined.


In tasinabilir.sh line 3:
if [[ ${#kodlar[@]} -gt 1 ]]; then
   ^-----------------------^ SC3010 (warning): In POSIX sh, [[ ]] is undefined.
```

Bu, Betik Anatomisi dersindeki kuralın araçla uygulanmasıdır: POSIX bildirip bash özelliği
kullanmak, betiğin başka bir sistemde sessizce bozulmasına yol açar. Aynı betik bash
bildirdiğinde bu iki uyarı üretilmez.

Denetimin sınırı da buradan görülür: araç, bildirilen kabuğa göre karar verir. Bildirim
yanlışsa denetim de yanlış yapılır. Bu yüzden yorumlayıcı bildirimi, betiğin gerçekten
kullandığı özelliklere göre yazılmalıdır.

## Uyarı Bastırma

Bir uyarının bilinçli olarak yok sayılması gerektiğinde, kaynak koda bir yönerge yazılır:

```sh
#!/usr/bin/env bash
# shellcheck disable=SC2086
kutuk="a b.log"
echo $kutuk
```

Yönerge, kendisinden **sonraki** komuta uygulanır; dosyanın başına, ilk komuttan önce
konursa tüm dosyayı kapsar.

Bastırma üç kurala bağlıdır.

**Kimlik verilir.** `disable` yönergesi kimliksiz yazılabilir ama o zaman tüm uyarıları
kapatır ve gelecekte oluşacak gerçek hataları da gizler.

**Kapsam daraltılır.** Dosya düzeyinde bastırma, o dosyadaki her satırı denetimden
çıkarır. Uyarının doğduğu satırın hemen üstüne yazmak yeğlenir.

**Gerekçe yazılır.** Bastırılan uyarının neden yanlış alarm olduğu bir yorumla belirtilir.
Gerekçesiz bir bastırma, kodu okuyan bir sonraki kişi için "burada ne olduğunu bilmiyorum"
demektir.

Kelime bölmenin gerçekten istendiği durumlarda daha iyi bir çözüm vardır: değeri bir diziye
almak. `"${dizi[@]}"` yazımı hem uyarı üretmez hem de niyeti kodda görünür kılar. Bastırma,
yeniden yazmanın mümkün olmadığı hâllere bırakılır.

## Betiği Denetimden Geçirmek

`rapor.sh` bu kurs boyunca, çözümleyicinin uyaracağı desenlerden kaçınılarak yazıldı.
Aşağıdaki küçük betik aynı kuralları izler:

```sh
#!/usr/bin/env bash
set -Eeuo pipefail
kutuk="${1:-erisim.log}"
[ -r "$kutuk" ] || { echo "okunamiyor: $kutuk" >&2; exit 3; }
adet=$(grep -c '' "$kutuk")
printf 'satir: %d\n' "$adet"
```

```sh
shellcheck temiz.sh; echo "kod=$?"
```

```
kod=0
```

Çıkış kodu `0` ve hiçbir çıktı yok. Araç, bulgu varsa sıfırdan farklı kod döndürür; bu,
denetimi bir doğrulama adımına dönüştürmeyi mümkün kılar:

```sh
shellcheck rapor.sh && bash -n rapor.sh && echo "denetim gecti"
```

Sürüm denetim sistemine gönderim öncesinde ya da bir sürekli tümleştirme adımında bu
komutun çalıştırılması, kabuk betiklerinin kalitesini korumanın en ucuz yoludur.

## Statik Çözümlemenin Sınırı

Araç, kodun **anlamını** değil **biçimini** görür. Yakalayamadıkları:

- Yanlış alan numarası (`$7` yerine `$8` yazmak).
- Yanlış düzenli ifade (kalıp geçerli ama beklenen kümeyi betimlemiyor).
- Yanlış iş mantığı (yüzdenin yanlış toplama bölünmesi).
- Çalışma ortamına bağlı hatalar (var olmayan komut, yetersiz izin).

Bu sınıflar için sınama gerekir: betiği bilinen bir girdiyle çalıştırıp çıktısını beklenen
çıktıyla karşılaştırmak. Bu kursun `erisim.log` dosyasının sabit ve yeniden üretilebilir
olması, tam olarak böyle bir sınamayı mümkün kılmak içindir.

Statik çözümleme sınamanın yerini tutmaz; sınamanın bulacağı hata sayısını azaltır.

## Özet

- Statik çözümleme, betiği çalıştırmadan ayrıştırıp bilinen hatalı desenleri arar.
- Yakalanan başlıca sınıflar tırnaklama, çıkış kodu, kabuk deyimleri ve tanımsız adlardır;
  hepsi bu kursta ayrı derslerin konusuydu.
- Denetim, yorumlayıcı bildirimine göre yapılır; POSIX bildiren betikte bash eklentileri
  uyarı üretir.
- Bastırma kimlikle, dar kapsamla ve gerekçeyle yapılır; kelime bölme isteniyorsa doğru
  çözüm dizi kullanmaktır.
- Araç bulgu varsa sıfırdan farklı kod döndürür; bu, denetimi bir doğrulama adımına
  çevirir.
- Statik çözümleme biçimi görür, anlamı görmez; yanlış alan numarası ve yanlış iş mantığı
  ancak sınamayla bulunur.

## Sonraki Adım

Betik doğru, sağlam ve denetlenmiş durumda — ama hâlâ elle çalıştırılıyor. Bir raporun
değeri düzenli üretilmesindedir. Son ders zamanlanmış görevleri ele alır: süreli görev
tanımının okunması, zamanlayıcı ortamının etkileşimli kabuktan hangi noktalarda ayrıldığı,
çıktının nereye yazılacağı ve üst üste binen çalışmaların engellenmesi.
