---
title: "Linux'a Giriş"
source: 'https://academia.sh/tr/kurslar/linuxa-giris'
language: tr
updated: '2026-08-17T04:41:45+00:00'
license: 'CC BY-SA 4.0'
lessons: 20
outcomes:
    - 'Dosya sistemi hiyerarşisinde komut satırıyla gezinir ve dosya işlemlerini yürütür'
    - 'Dosya izinlerini ve sahipliğini okuyup değiştirir'
    - 'Paket yöneticisiyle yazılım kurar, günceller ve kaldırır'
---

# Linux'a Giriş

Kabuk, dosya sistemi hiyerarşisi, dosya ve dizin işlemleri, izin modeli ve paket yönetimi; komut satırının neden öyle davrandığını açıklayan bir giriş.

## Sistemle Tanışma

Çekirdek, dağıtım ve kabuk ayrımı; komut yapısı, dizin hiyerarşisi, kılavuz sayfaları ve çalıştırılabilir arama sırası.

### Unix Geleneği ve Linux

Source: https://academia.sh/tr/kurslar/linuxa-giris/unix-gelenegi-ve-linux

Çekirdek, dağıtım ve kabuk katmanlarının ayrımı; Unix tasarım geleneğinin taşıdığı varsayımlar ve POSIX'in taşınabilirlik sözü.

"Linux öğrenmek" ifadesi, tek bir şeyi değil üst üste duran üç ayrı katmanı kapsar:
donanımı yöneten çekirdek, çekirdeğin çevresine toplanmış program kümesi ve bu
programları çağırmak için kullanılan komut yorumlayıcı. Üçü farklı kurumlarca, farklı
zamanlarda ve farklı gerekçelerle üretilmiştir; her biri ayrı ayrı değiştirilebilir.

Bu ders katmanları ayırır ve kursun geri kalanının hangi katmanda geçtiğini belirler.
Ayrım gereksiz bir titizlik gibi görünebilir; ancak "komut çalışmıyor" türü sorunların
çoğu, sorunun hangi katmanda olduğunu bilmemekten kaynaklanır.

#### Unix Geleneğinin Varsayımları

Linux, 1970'lerde Bell Laboratuvarları'nda geliştirilen **Unix** işletim sisteminin
tasarım geleneğini sürdürür. Bu gelenek birkaç varsayım üzerine kuruludur ve
varsayımlar, komutların bugünkü davranışını doğrudan açıklar.

**Her şey bir dosyadır.** Yalnızca disk üzerindeki veriler değil; aygıtlar, terminaller,
süreçler arası iletişim kanalları da dosya sistemi içinde bir adla temsil edilir.
Programlar tek bir arayüzle — aç, oku, yaz, kapat — hepsine erişir.

**Küçük araçlar, tek iş.** Her program dar bir işi yapar. Karmaşık işler, programları
birleştirerek kurulur. Bu birleştirmenin dilbilgisi Kabuk Programlama kursunun konusudur;
bu kurs araçların kendisini tanıtır.

**Metin ortak arayüzdür.** Programlar arasında akan veri, çoğunlukla satırlara bölünmüş
düz metindir. Metin, hem insan hem program tarafından okunabildiği için ortak payda
olarak seçilmiştir.

**Yapılandırma dosyalarda durur.** Sistem davranışı, ikili biçimli gizli bir kayıt
defterinde değil, okunabilir metin dosyalarında tutulur. Bir ayarı incelemek, ilgili
dosyayı okumaktır.

Bu varsayımlar bir tasarım tercihidir, doğa yasası değildir. Bedelleri de vardır: metin
tabanlı arayüz, yapılandırılmış veriyi ayrıştırma yükünü her programa dağıtır. Kursun
ilerleyen derslerinde bu bedelin nerede ödendiği görünecektir.

#### Çekirdek

**Çekirdek (kernel)**, donanımla doğrudan konuşan tek yazılım katmanıdır. Sorumlulukları
Bilgisayarlar Nasıl Çalışır kursunda tanıtılan kavramlarla örtüşür:

- **Süreç zamanlama:** Hangi programın ne zaman işlemciyi kullanacağına karar verir. Bu
  kararın uygulanması, kesmeler dersinde anlatılan zamanlayıcı kesmesine dayanır.
- **Bellek yönetimi:** Her sürece kendi adres uzayını verir; bir sürecin diğerinin
  belleğini okumasını engeller.
- **Dosya sistemi:** Diskteki bloklara ad ve dizin yapısı giydirir.
- **Aygıt sürücüleri:** Klavye, disk, ağ arayüzü gibi donanımların ayrıntısını gizler.

Bir program çekirdeğin hizmetine **sistem çağrısı (system call)** ile ulaşır. Sistem
çağrısı, sıradan bir işlev çağrısı değildir: işlemci ayrıcalık düzeyini değiştirir,
denetim çekirdeğe geçer, iş bitince geri döner. Dosya açmak, bellek istemek, süreç
yaratmak birer sistem çağrısıdır.

Bu sınır önemlidir çünkü **taşınabilirliğin de sınırıdır**: aynı sistem çağrısı arayüzünü
sunan iki farklı çekirdek üzerinde aynı program çalışabilir.

Sistemin hangi çekirdeği çalıştırdığı sorulabilir:

```
$ uname -s
Linux
```

`uname` komutu çekirdeğin adını yazdırır. Aynı komut, Unix geleneğini paylaşan başka bir
sistemde başka bir yanıt verir — örneğin macOS üzerinde `Darwin`. Komutun kendisi her
ikisinde de vardır; yanıt farklıdır. Taşınabilirliğin ne demek olduğunun en kısa
gösterimi budur.

#### Dağıtım

Çekirdek tek başına kullanılabilir bir sistem değildir. Dosya kopyalayan, metin
görüntüleyen, ağ bağlantısı kuran programlar çekirdeğin parçası değildir; ayrı
projelerdir.

**Dağıtım (distribution)**, bir çekirdeği seçilmiş bir program kümesiyle birleştirip
kurulabilir bir bütün hâline getiren paketleme çalışmasıdır. Bir dağıtım tipik olarak şu
bileşenleri belirler:

- Çekirdek ve sürücü seçimi
- Standart C kütüphanesi
- Temel komut araçları (dosya, metin, süreç araçları)
- İlk süreci başlatan ve servisleri yöneten sistem
- Paket yöneticisi ve depo yapılandırması
- Varsayılan kabuk ve varsayılan editör

Bu seçimler dağıtımdan dağıtıma değişir. Bu kurs, değişen kısımlara değil **ortak
zemine** bağlı kalır: anlatılan komutların çoğu POSIX'te tanımlıdır veya tüm yaygın
dağıtımlarda aynı adla bulunur. Dağıtıma özgü davranış geçtiğinde bu açıkça belirtilir.

**POSIX**, Unix benzeri sistemlerin arayüzünü tanımlayan bir standarttır. Bir komutun
POSIX'te tanımlı olması, adının ve temel seçeneklerinin standarda uyan her sistemde aynı
anlama geleceği anlamına gelir. Standart, her seçeneği kapsamaz: sistemler standarda ek
seçenekler koyar ve bu ekler birbirinden ayrışır. Kurs boyunca bu ayrışmanın en sık
görülen örneği olan GNU ve BSD araç aileleri arasındaki farklar, geçtikleri yerde
gösterilir.

#### Kabuk

**Kabuk (shell)**, kullanıcıdan komut satırı alan, onu yorumlayan ve karşılık gelen
programları çalıştıran bir programdır. Çekirdeğin parçası değildir; ayrıcalıklı değildir;
başka herhangi bir program gibi çalışır ve değiştirilebilir.

Hangi kabuğun çalıştığı, süreç listesinden okunabilir:

```
$ ps -p $$ -o pid=,comm=
 1076 bash
$ echo $$
1076
```

`$$`, kabuğun kendi süreç numarasını tutan bir değişkendir. `ps` komutu o numaralı sürecin
adını yazdırır. Buradaki yanıt kabuğun adıdır — sistemden sisteme ve kullanıcıdan
kullanıcıya değişir.

Kabuğun değiştirilebilirliği, sistemin bir yerinde açıkça görünür:

```
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 31  2024 /bin/sh -> dash
```

`/bin/sh`, bir programın kendisi değil, bir **role** verilmiş addır: "POSIX kabuğu".
Çıktının ilk karakterindeki `l` harfi, bunun bir bağlantı olduğunu söyler; ok işareti
gerçek hedefi gösterir. Bu sistemde rol `dash` adlı kabuğa verilmiştir; başka bir sistemde
başka bir programa verilebilir. Bağlantıların nasıl çalıştığı, dosya işlemleri konusunda
ayrıntılı olarak ele alınacaktır.

Ayrım şuraya varır: bir komut "çalışmıyorsa" üç ayrı olasılık vardır. Komut sistemde kurulu
değildir (dağıtım katmanı), kabuk komutu bulamıyordur (kabuk katmanı) veya çekirdek işlemi
reddediyordur (izin katmanı). Bu kursun konularının sırası bu üç katmanı izler.

#### Her Şey Bir Dosyadır — Somut Bir Örnek

Varsayımların en soyutu olan "her şey bir dosyadır" ilkesi, aygıtlara bakılarak
doğrulanabilir:

```
$ ls -l /dev/null /dev/zero
crw-rw-rw- 1 root root 1, 3 Jul 26 18:45 /dev/null
crw-rw-rw- 1 root root 1, 5 Jul 26 18:45 /dev/zero
```

Satır başındaki `c` harfi, bu girdilerin sıradan dosya değil **karakter aygıtı** olduğunu
söyler. Sıradan bir dosyanın boyutunun bulunduğu sütunda burada iki sayı vardır: aygıtın
ana ve alt numarası. Çekirdek bu numaralarla hangi sürücünün çağrılacağını belirler.

`/dev/null` yazılan her şeyi yutar ve okunduğunda hemen dosya sonu verir; `/dev/zero`
okundukça sıfır bayt üretir. İkisi de disk üzerinde veri tutmaz. Yine de bir program
onları sıradan bir dosya gibi açar, okur ve yazar — çünkü arayüz ortaktır.

#### Kursun Ekseni

Kurs boyunca tek bir örnek üzerinde çalışılacaktır: ev dizini altında kurulan `proje/`
adlı bir ölçüm çalışması. Bu dizin ağacı her derste bir adım ilerler; ham ölçüm dosyaları
eklenir, işlenir, bağlanır, arşivlenir, izinleri düzenlenir ve sonunda bir grupla
paylaşılır.

Amaç, komutları listelemek değil, her komutun **neden** öyle davrandığını aynı somut ağaç
üzerinde göstermektir. Bir sonraki ders bu ağacı kurmadan önce, komutların kendisini
yorumlayan katmanı — kabuğu — inceler.

#### Özet

- Unix geleneği dört varsayıma dayanır: her şey bir dosyadır, araçlar küçük ve tek işlidir,
  ortak arayüz metindir, yapılandırma okunabilir dosyalarda durur.
- Çekirdek donanımı yönetir ve hizmetlerini sistem çağrılarıyla sunar; bu sınır aynı
  zamanda taşınabilirliğin sınırıdır.
- Dağıtım, bir çekirdeği seçilmiş programlarla birleştiren paketleme çalışmasıdır;
  değişen kısımdır.
- POSIX, komut adlarının ve temel seçeneklerinin ortak anlamını tanımlar; sistemlerin
  standarda eklediği seçenekler birbirinden ayrışır.
- Kabuk ayrıcalıklı bir bileşen değil, değiştirilebilir bir programdır; `/bin/sh` bir
  programın değil bir rolün adıdır.

#### Sonraki Adım

Katmanlar ayrıldığına göre, sıra en üsttekine gelir. Bir komut satırı yazıldığında kabuk
onu tam olarak ne yapar: sözcüklere nasıl böler, hangi kısmı program adı sayar, tırnak
işaretleri neyi değiştirir ve bir komutun başarılı olup olmadığı nereden anlaşılır? Sonraki
ders kabuğun bu ayrıştırma işini adım adım açar.

### Kabuk Nedir

Source: https://academia.sh/tr/kurslar/linuxa-giris/kabuk-nedir

İstem, komut satırının sözcüklere ayrılması, açılımların komuttan önce yapılması, seçenek biçimleri, yerleşik komutlar ve çıkış durumu.

Önceki ders kabuğu, komutları yorumlayan değiştirilebilir bir program olarak tanımladı.
Bu tanım henüz bir şey açıklamaz: kabuk yazılan satırı tam olarak ne yapar?

Sorunun yanıtı, komut satırının en sık yapılan hatalarını da açıklar. Boşluk içeren bir
dosya adı neden iki ayrı argümana bölünür, yıldız işaretini gerçekte kim yorumlar, bir
komutun başarılı olup olmadığı nereden anlaşılır — hepsi tek bir ayrıştırma sürecinin
sonucudur.

#### İstem

Kabuk, komut beklediğini **istem (prompt)** ile bildirir. İstemin içeriği
yapılandırılabilir; kullanıcı adı, makine adı ve bulunulan dizin yaygın olarak gösterilir.
Bu kursun örneklerinde istem tek bir karakterle gösterilir:

```
$ echo Merhaba
Merhaba
```

`$` ile başlayan satırlar yazılan komuttur; altındaki satırlar komutun ürettiği çıktıdır.
Belgelerde yerleşik bir gelenek vardır: sıradan kullanıcı istemi `$`, süper kullanıcı
istemi `#` ile gösterilir. Bir belgede `#` ile başlayan komut görülürse, o komutun
yönetici yetkisi gerektirdiği anlaşılır.

#### Satır Sözcüklere Bölünür

Kabuk satırı önce **sözcüklere** böler. Bölme, boşluk karakterleriyle yapılır ve ardışık
boşluklar tek bir ayırıcı sayılır. İlk sözcük çalıştırılacak programın adıdır; kalan
sözcükler ona **argüman** olarak geçirilir.

```
$ echo Merhaba    dunya
Merhaba dunya
```

Çıktıda dört boşluk yerine bir boşluk vardır. Bunun nedeni `echo` komutunun boşlukları
sıkıştırması değildir: `echo` iki argüman almıştır — `Merhaba` ve `dunya` — ve onları tek
boşlukla birleştirerek yazdırmıştır. Aradaki boşluklar `echo` çalışmadan önce yok
olmuştur.

Argüman sayısı doğrudan sayılabilir:

```
$ dosya="olcum 01.csv"
$ set -- $dosya; echo $#
2
$ set -- "$dosya"; echo $#
1
```

`$#` argüman sayısını verir. Değişkenin değeri tırnaksız yazıldığında kabuk onu iki
sözcüğe bölmüş, tırnak içinde yazıldığında tek sözcük olarak bırakmıştır. Boşluk içeren
dosya adlarının neden tırnak içinde yazılması gerektiğinin nedeni budur; aksi hâlde komut,
var olmayan iki dosya arar.

Aynı fark, sözcük sınırlarını görünür kılan bir yazdırma biçimiyle de gösterilebilir:

```
$ printf '[%s]\n' $dosya
[olcum]
[01.csv]
$ printf '[%s]\n' "$dosya"
[olcum 01.csv]
```

#### Açılımlar Komuttan Önce Yapılır

Sözcüklere bölme tek işlem değildir. Kabuk, program çalışmadan önce sözcükler üzerinde
birkaç **açılım (expansion)** uygular. Bu kursta üçü kullanılır: değişken açılımı (`$ad`),
dosya adı açılımı (`*`, `?`) ve ev dizini açılımı (`~`).

Belirleyici nokta şudur: açılımı yapan kabuktur, çalıştırılan program değil. Program
yalnızca açılım sonucunu görür.

```
$ echo /usr/bin/zc*
/usr/bin/zcat /usr/bin/zcmp
$ ls /usr/bin/zc*
/usr/bin/zcat  /usr/bin/zcmp
```

İki komut da aynı iki dosya adını üretmiştir. `ls` komutuna `*` karakteri hiç
ulaşmamıştır; kabuk deseni eşleşen dosya adlarıyla değiştirmiş, `ls` iki hazır argüman
almıştır. `echo` ile `ls` çıktısı arasındaki tek fark, `ls` sütun hizalaması yapmasıdır.

Bunun iki sonucu vardır. Birincisi, desen hiçbir dosyayla eşleşmezse kabuk deseni olduğu
gibi bırakır ve program `*` içeren anlamsız bir ad alır. İkincisi ve daha önemlisi, bir
komutun ne yapacağı **önceden görülebilir**: komutun başına `echo` yazmak, kabuğun
üreteceği argüman listesini çalıştırmadan gösterir. Bu, silme işlemleri dersinde bir
güvenlik alışkanlığına dönüşecektir.

Tırnak, açılımı da durdurur:

```
$ echo "/usr/bin/zc*"
/usr/bin/zc*
```

Çift tırnak dosya adı açılımını ve sözcük bölmeyi engeller, değişken açılımını
engellemez. Tek tırnak hepsini engeller: tek tırnak içindeki metin harfi harfine
korunur.

#### Seçenekler ve Argümanlar

Bir komut satırının argümanları iki türlüdür. **Seçenek (option)** komutun davranışını
değiştirir ve gelenek olarak tire ile başlar; kalanlar komutun üzerinde çalışacağı
nesnelerdir.

Seçeneklerin üç yazım biçimi vardır ve üçü de aynı sonucu verir:

```
$ ls -l -a /home
total 16
drwxr-xr-x 1 root    root    4096 Jul 26 18:53 .
drwxr-xr-x 1 root    root    4096 Jul 26 18:46 ..
drwxr-x--- 3 ogrenci ogrenci 4096 Jul 26 18:49 ogrenci
$ ls -la /home
total 16
drwxr-xr-x 1 root    root    4096 Jul 26 18:53 .
drwxr-xr-x 1 root    root    4096 Jul 26 18:46 ..
drwxr-x--- 3 ogrenci ogrenci 4096 Jul 26 18:49 ogrenci
```

Tek harfli seçenekler tek tire ile yazılır ve birleştirilebilir: `-l -a` ile `-la` aynı
şeydir. Uzun seçenekler iki tire ile yazılır (`--all`) ve birleştirilemez; her biri ayrı
sözcüktür. Uzun seçenek biçimi POSIX'te tanımlı değildir, GNU araç ailesinin eklentisidir;
taşınabilir olması gereken yerlerde tek harfli biçim tercih edilir.

Tire ile başlayan bir **dosya adı** varsa sorun çıkar: komut onu seçenek sanır. Bunun için
`--` ayıracı vardır. `--` sözcüğünden sonrası seçenek olarak yorumlanmaz. Bu ayıracın
neden bir güvenlik konusu olduğu, silme dersinde görülecektir.

#### Yerleşik Komut ve Dış Program

Her komut ayrı bir program değildir. Bazı komutlar kabuğun kendi içinde
gerçekleştirilmiştir; bunlara **yerleşik komut (builtin)** denir. Bir adın hangisi olduğu
sorulabilir:

```
$ type -a cd pwd echo
cd is a shell builtin
pwd is a shell builtin
pwd is /usr/bin/pwd
pwd is /bin/pwd
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo
```

Üç farklı durum görünür. `cd` yalnızca yerleşiktir. `pwd` ve `echo` hem yerleşiktir hem de
dış program olarak vardır; bu durumda yerleşik olan kazanır.

`cd`'nin yerleşik olması bir tercih değil, zorunluluktur. Bir programın çalışma dizini
kendi sürecine aittir; ayrı bir program olarak çalışan `cd`, kendi dizinini değiştirip
sonlanır ve kabuğun dizini olduğu yerde kalırdı. Dizin değiştirmek için komutun kabuğun
**kendi süreci içinde** çalışması gerekir.

`echo`'nun hem yerleşik hem dış program olması ise taşınabilirlik içindir: kabuğu olmayan
ortamlarda da çağrılabilmesi gerekir. İki gerçekleştirimin davranışı tam olarak aynı
değildir; bu nedenle biçimli çıktıda `echo` yerine `printf` tercih edilir.

#### Çıkış Durumu

Her komut sonlandığında geriye bir tam sayı bırakır: **çıkış durumu (exit status)**.
Sözleşme tersine kuruludur — sıfır başarıyı, sıfırdan farklı her değer bir başarısızlığı
bildirir. Tek bir başarı, sayısız başarısızlık türü olduğu için bu yön seçilmiştir.

Son komutun durumu `$?` değişkeninde tutulur:

```
$ true; echo $?
0
$ false; echo $?
1
$ ls /yokdizin; echo $?
ls: cannot access '/yokdizin': No such file or directory
2
```

`ls` başarısızlığı hem bir hata iletisiyle hem de sıfırdan farklı bir durumla bildirir.
İleti insan içindir; durum kodu, komutları birbirine bağlayan betikler içindir.

İki değer kabuğun kendisinden gelir ve ayırt edilmesi gerekir:

```
$ lss -l
bash: lss: command not found
$ echo $?
127
```

**127** komutun bulunamadığını, **126** bulunduğunu ama çalıştırılamadığını bildirir.
Birincisi bir arama sorunudur, ikincisi bir izin sorunu. Bu iki sayının farkı, sonraki
dersin ve izinler konusunun tam olarak neyi çözdüğünü gösterir.

Hata iletilerinin nereye yazıldığı da ayrı bir konudur: normal çıktı ile hata çıktısı iki
ayrı akıştır ve birbirinden bağımsız yönlendirilebilir. Bu ayrımın kullanımı Kabuk
Programlama kursuna aittir.

#### Özet

- Kabuk satırı önce sözcüklere böler; ilk sözcük program adı, kalanlar argümandır.
- Değişken, dosya adı ve ev dizini açılımları program çalışmadan önce kabukta yapılır;
  program yalnızca sonucu görür.
- Çift tırnak sözcük bölmeyi ve dosya adı açılımını durdurur, değişken açılımını
  durdurmaz; tek tırnak hepsini durdurur.
- Tek harfli seçenekler birleştirilebilir, uzun seçenekler birleştirilemez; `--` ayıracı
  seçenek yorumlamasını bitirir.
- Yerleşik komutlar kabuğun kendi sürecinde çalışır; `cd` bu nedenle yerleşik olmak
  zorundadır.
- Çıkış durumunda sıfır başarıyı gösterir; 127 komutun bulunamadığını, 126
  çalıştırılamadığını bildirir.

#### Sonraki Adım

Komutlar artık üzerinde çalışacak dosyalara ihtiyaç duyar. Ancak dosyalar rastgele
yerleştirilmemiştir: kök dizinden başlayan hiyerarşinin her dalının belirli bir anlamı
vardır. Sonraki ders bu yerleşimi tanıtır, mutlak ve göreli yol ayrımını kurar ve kurs
boyunca geliştirilecek proje ağacını oluşturur.

### Dizin Hiyerarşisi

Source: https://academia.sh/tr/kurslar/linuxa-giris/dizin-hiyerarsisi

Tek köklü dosya ağacı, takma noktaları, standart dizin yerleşimi ve yolların adım adım çözümlenmesi; kurs boyunca kullanılacak proje ağacının kurulması.

Komutlar dosyalar üzerinde çalışır; dosyalar da rastgele yerlerde durmaz. Unix
sistemlerinde her dosyanın adresi, tek bir ağacın kökünden başlayan bir yoldur ve ağacın
her dalının belirli bir anlamı vardır.

Bu ders yerleşimin mantığını kurar, bir yolun çekirdek tarafından nasıl çözümlendiğini
açıklar ve kurs boyunca üzerinde çalışılacak `proje/` ağacını oluşturur.

#### Tek Kök

Dosya sistemi tek bir ağaçtır ve kökü `/` ile gösterilir. Sürücü harfi yoktur; ikinci bir
disk, ikinci bir ağaç açmaz. Bunun yerine diskler ağacın bir dalına **takılır (mount)**.

Takma, bir depolama aygıtının içeriğini var olan bir dizin üzerinde görünür kılmaktır.
Takıldıktan sonra o dizine giren bir program, farklı bir aygıta eriştiğini fark etmez;
yol yine aynı ağacın parçasıdır. Aygıt sınırının nerede olduğu, yalnızca aygıtlar arası
işlem yapılırken önem kazanır — sabit bağlantılar ve taşıma işlemleri dersinde bu sınırın
neyi engellediği görülecektir.

Kökün üstü yoktur. Kök dizinde `..` yine kökü gösterir:

```
$ cd /
$ pwd
/
$ cd ..
$ pwd
/
```

Bu, hata değil tanımdır: ağacın en üstünde bir üst yoktur ve `..` kendine döner. Yol
çözümlemesi bu sayede kökün dışına çıkamaz.

#### Standart Yerleşim

Kök altındaki dizinlerin adları ve işlevleri bir yerleşim standardıyla belirlenmiştir.
Standart, hangi türden dosyanın nereye konacağını söyler; böylece bir yönetici tanımadığı
bir sistemde de aradığını nerede bulacağını bilir.

| Dizin | İçerik |
|---|---|
| `/bin`, `/usr/bin` | Tüm kullanıcıların çalıştırdığı temel komutlar |
| `/sbin`, `/usr/sbin` | Sistem yönetimi komutları |
| `/lib`, `/usr/lib` | Paylaşılan kütüphaneler |
| `/etc` | Sisteme özgü yapılandırma dosyaları |
| `/home` | Kullanıcı ev dizinleri |
| `/root` | Süper kullanıcının ev dizini |
| `/var` | Boyutu değişen veriler: kütükler, kuyruklar, önbellekler |
| `/tmp` | Geçici dosyalar; yeniden başlatmada silinebilir |
| `/opt` | Ek uygulama yazılım paketleri |
| `/dev` | Aygıt düğümleri |
| `/proc`, `/sys` | Çekirdek durumunu dosya olarak sunan sanal dosya sistemleri |
| `/boot` | Çekirdek görüntüsü ve önyükleyici dosyaları |
| `/mnt`, `/media` | Geçici takma noktaları |

Yerleşimin arkasında iki ayrım vardır. Birincisi **değişen ile değişmeyen** ayrımıdır:
`/usr` altındaki içerik yalnızca yazılım kurulunca değişir, `/var` altındaki içerik sistem
çalışırken sürekli değişir. İkincisi **paylaşılabilir ile yerel** ayrımıdır: `/usr` birden
çok makinede ortak kullanılabilir, `/etc` o makineye özgüdür. Bu iki ayrım, dizinlerin
ayrı bölümlere yerleştirilmesini ve farklı yedekleme politikaları uygulanmasını mümkün
kılar.

Standart bir yerleşim, tarihsel nedenlerle bölünmüş bazı dalları tek noktada birleştirir:

```
$ ls -l /bin /lib
lrwxrwxrwx 1 root root 7 Apr 22  2024 /bin -> usr/bin
lrwxrwxrwx 1 root root 7 Apr 22  2024 /lib -> usr/lib
```

Bu sistemde `/bin` ayrı bir dizin değil, `/usr/bin`'e işaret eden bir bağlantıdır.
`/bin/ls` ile `/usr/bin/ls` aynı dosyadır. Eski yolların çalışmaya devam etmesi, geriye
dönük uyumluluk içindir.

#### Mutlak ve Göreli Yol

**Mutlak yol**, kökten başlar ve `/` karakteriyle başlayan bir dizedir:
`/home/ogrenci/proje/veri`. Nerede olunursa olunsun aynı dosyayı gösterir.

**Göreli yol**, bulunulan dizinden başlar ve `/` ile başlamaz: `veri/ham`. Hangi dosyayı
gösterdiği, o anki **çalışma dizinine (working directory)** bağlıdır.

Çalışma dizini, kabuğun değil sürecin bir özelliğidir; her sürecin kendi çalışma dizini
vardır ve çocuk süreçler onu miras alır. `pwd` komutu bu değeri yazdırır.

Üç özel ad her dizinde geçerlidir:

- `.` — bulunulan dizinin kendisi
- `..` — üst dizin
- `~` — ev dizini; bu bir dizin adı değil, kabuğun yaptığı bir açılımdır

`.` ve `..` gerçek dizin girdileridir; çekirdek onları her dizinde tutar. `~` ise
kabuğa aittir ve komuta ulaşmadan önce ev dizininin mutlak yoluna çevrilir.

#### Yol Nasıl Çözümlenir

Bir yol, çekirdek tarafından **bileşen bileşen** çözümlenir. `/home/ogrenci/proje` yolu
için sıra şudur: kök dizin açılır, içinde `home` adı aranır, bulunan dizin açılır, içinde
`ogrenci` aranır, o dizin açılır, içinde `proje` aranır.

Bu adım adım yürüyüşün üç sonucu vardır ve üçü de kursun ilerleyen derslerinde tekrar
karşımıza çıkar:

**Her adım bir arama gerektirir.** Yol ne kadar derinse o kadar çok dizin okunur.

**Her ara dizinde geçiş izni aranır.** Yolun sonundaki dosyaya erişmek için, yol
üzerindeki her dizinde çalıştırma izni gerekir. İzin bitleri dersinde bu, dizinler için
`x` bitinin neden "geçiş hakkı" anlamına geldiğini açıklayacaktır.

**Ara bileşenler bağlantı olabilir.** Yol üzerinde bir sembolik bağla karşılaşılırsa
çözümleme hedeften devam eder. `/bin/ls` yolunun `/usr/bin/ls` dosyasına varması bu
yüzdendir.

Göreli yol da aynı biçimde çözümlenir; tek farkı, kökten değil çalışma dizininden
başlamasıdır:

```
$ cd /home/ogrenci/proje/veri
$ pwd
/home/ogrenci/proje/veri
$ cd -
/
$ pwd
/
```

`cd -` bir önceki dizine döner ve döndüğü dizini yazdırır. Bu, iki dizin arasında sık
geçiş yaparken kullanılan bir kısayoldur.

#### Gizli Dosyalar

Adı nokta ile başlayan dosyalar, listelemede varsayılan olarak gösterilmez:

```
$ ls
proje
$ ls -a
.  ..  .bash_history  .bash_logout  .bashrc  .profile  proje
```

Bu bir güvenlik özelliği değil, bir görüntüleme geleneğidir. Çekirdek açısından nokta ile
başlayan adın hiçbir ayrıcalığı yoktur; yalnızca listeleme araçları onları varsayılan
olarak atlar. Gelenek, kullanıcı yapılandırma dosyalarının ev dizinini
doldurmamasını sağlar.

`ls -a` çıktısındaki ilk iki girdi `.` ve `..`'dır; her dizinde bulunan gerçek girdiler
oldukları burada görünür.

#### Proje Ağacının Kurulması

Kurs boyunca kullanılacak ağaç ev dizini altında kurulur. Ölçüm verisi, işlenmiş çıktı,
betik, belge ve arşiv ayrı dallara yerleştirilir — kök altındaki yerleşimin küçük ölçekte
yinelenmesi:

```
$ mkdir -p proje/veri/ham proje/veri/islenmis
$ mkdir -p proje/betik proje/belge proje/arsiv
$ find proje -type d | sort
proje
proje/arsiv
proje/belge
proje/betik
proje/veri
proje/veri/ham
proje/veri/islenmis
```

`mkdir` normalde yalnızca tek düzey dizin oluşturur ve üst dizini yoksa hata verir. `-p`
seçeneği eksik ara dizinleri de oluşturur ve dizin zaten varsa hata vermez. İkinci
özellik, aynı komutun yeniden çalıştırılabilir olmasını sağlar.

`find` komutu bir ağacı özyinelemeli olarak dolaşır; `-type d` yalnızca dizinleri seçer.
Çıktı sıralı değildir — dosya sistemi girdileri sırasız döndürebilir — bu yüzden `sort`
ile sıralanmıştır.

Ağacın anlamı şudur: `veri/ham` dışarıdan gelen ve **değiştirilmeyecek** ölçüm dosyalarını,
`veri/islenmis` bunlardan türetilen çıktıları tutar. `betik` işlemi yapan programları,
`belge` açıklamaları, `arsiv` paketlenmiş sürümleri tutar. Ham veriyi ayrı ve dokunulmaz
tutmak, silme dersinde geri alınamazlık tartışmasının merkezinde olacaktır.

#### Özet

- Dosya sistemi tek köklüdür; ek diskler yeni bir ağaç açmaz, var olan bir dizine takılır.
- Kök altındaki yerleşim standarttır ve iki ayrıma dayanır: değişen/değişmeyen ve
  paylaşılabilir/yerel.
- Mutlak yol kökten, göreli yol çalışma dizininden başlar; çalışma dizini sürecin bir
  özelliğidir.
- Yol bileşen bileşen çözümlenir; her ara dizinde geçiş izni aranır ve ara bileşenler
  bağlantı olabilir.
- Nokta ile başlayan adların gizliliği bir listeleme geleneğidir, çekirdek düzeyinde bir
  ayrıcalık değildir.
- `mkdir -p` eksik ara dizinleri oluşturur ve var olan dizinde hata vermez.

#### Sonraki Adım

Ağaç kuruldu, ancak komutların seçenekleri ve davranışları henüz ezberle öğrenilmek
durumunda. Sistemin kendisi bunu gereksiz kılar: her komutun kendi belgesi sistemde
kuruludur ve belgeler numaralı bölümlere ayrılmış tutarlı bir yapı izler. Sonraki ders bu
belgelerin nasıl okunacağını ve aynı adın farklı bölümlerde neden farklı şeyler
anlatabildiğini gösterir.

### Yardım Kaynakları

Source: https://academia.sh/tr/kurslar/linuxa-giris/yardim-kaynaklari

Kılavuz sayfalarının bölüm numaraları, sayfa yapısı ve kullanım özeti gösterimi; yerleşik komutlar için yardım ve komut türünü belirleme.

Önceki derste `mkdir -p` seçeneği kullanıldı ve ne yaptığı metinde açıklandı. Bu
sürdürülebilir bir öğrenme biçimi değildir: yüzlerce komutun onlarca seçeneği ezberlenmez.

Sistem bunu gerektirmez. Her komutun belgesi, komutun kendisiyle birlikte kurulur ve
belgeler tutarlı bir yapı izler. Bu ders o yapıyı tanıtır; kursun geri kalanında
seçeneklerin bir kısmı açıklanmak yerine okura bırakılacaktır.

#### Kılavuz Sayfaları

**Kılavuz sayfası (manual page)**, bir komutun, dosya biçiminin veya sistem çağrısının
başvuru belgesidir. `man` komutuyla görüntülenir:

```
$ man 1 ls | sed -n '1,13p'
LS(1)                            User Commands                           LS(1)

NAME
       ls - list directory contents

SYNOPSIS
       ls [OPTION]... [FILE]...

DESCRIPTION
       List  information  about  the FILEs (the current directory by default).
       Sort entries alphabetically if none of -cftuvSUX nor --sort  is  speci-
       fied.

```

Örnekte sayfanın yalnızca ilk satırları alınmıştır; doğrudan `man ls` yazıldığında sayfa
bir sayfalayıcı programda açılır ve ok tuşlarıyla gezilir, `q` ile çıkılır. Sayfalayıcı
içinde `/` ile arama yapılır.

Kılavuz sayfaları standart alt başlıklar taşır. Sırasıyla en çok kullanılanlar:

- **NAME** — komutun adı ve tek satırlık tanımı
- **SYNOPSIS** — kullanım özeti
- **DESCRIPTION** — ayrıntılı davranış ve seçenek listesi
- **EXIT STATUS** — hangi durumda hangi çıkış durumunun döneceği
- **FILES** — komutun okuduğu veya yazdığı dosyalar
- **SEE ALSO** — ilgili sayfalar

Bir komutun davranışını hızlı doğrulamak için sırasıyla NAME ve SYNOPSIS, ayrıntı için
DESCRIPTION okunur. Bir hatanın nedenini araştırırken EXIT STATUS ve FILES bölümleri
çoğu zaman doğrudan yanıt verir.

#### Kullanım Özetini Okumak

SYNOPSIS satırı bir gösterim düzeni kullanır ve bu düzen tüm kılavuz sayfalarında aynıdır:

| Gösterim | Anlamı |
|---|---|
| `düz metin` | Aynen yazılır |
| `[...]` | Köşeli parantez içindekiler isteğe bağlıdır |
| `...` | Kendinden önceki öge yinelenebilir |
| `a\|b` | Seçeneklerden biri |
| `BÜYÜK HARF` | Yerine değer konacak yer tutucu |

Buna göre `ls [OPTION]... [FILE]...` satırı şunu söyler: `ls` sıfır veya daha çok seçenek
ve sıfır veya daha çok dosya adı alır; ikisi de zorunlu değildir. Argümansız `ls`
çalışabilir; bu, DESCRIPTION'daki "varsayılan olarak bulunulan dizin" ifadesiyle
tutarlıdır.

Karşılaştırma için başka bir komutun özeti:

```
$ mkdir --help | head -9
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.

Mandatory arguments to long options are mandatory for short options too.
  -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask
  -p, --parents     no error if existing, make parent directories as needed,
                    with their file modes unaffected by any -m option.
  -v, --verbose     print a message for each created directory
  -Z                   set SELinux security context of each created directory
```

`DIRECTORY...` köşeli parantez içinde değildir: en az bir dizin adı zorunludur. Önceki
derste kullanılan `-p` seçeneğinin iki ayrı işlevi de burada yazılıdır — eksik üst
dizinleri oluşturmak ve var olan dizinde hata vermemek.

`--help` seçeneği kılavuz sayfasının yerini tutmaz; çoğu komutta yalnızca seçenek listesi
verir. Buna karşılık her zaman hızlıdır ve kılavuz sayfaları kurulu olmayan sistemlerde
tek kaynaktır.

#### Bölüm Numaraları

Kılavuz tek bir küme değil, numaralı **bölümlere** ayrılmıştır. Aynı ad birden çok bölümde
bulunabilir ve farklı şeyleri anlatır.

| Bölüm | İçerik |
|---|---|
| 1 | Kullanıcı komutları |
| 2 | Sistem çağrıları |
| 3 | Kütüphane işlevleri |
| 4 | Özel dosyalar ve aygıtlar |
| 5 | Dosya biçimleri ve yapılandırma dosyaları |
| 6 | Oyunlar |
| 7 | Çeşitli: kurallar, gösterimler, kavramlar |
| 8 | Sistem yönetimi komutları |

Bölüm ayrımının ne işe yaradığı tek bir adla gösterilebilir:

```
$ whatis passwd
passwd (1)           - change user password
passwd (1ssl)        - OpenSSL application commands
passwd (5)           - the password file
```

`passwd` hem bir komuttur hem de bir dosya biçimidir. Listedeki girdiler sistemde kurulu
paketlere bağlıdır; kurulu olmayan bir yazılımın sayfası görünmez. Ortadaki satırdaki
`1ssl` gibi son ekli bölüm adları, bir yazılımın kendi sayfalarını ayrı bir alt bölümde
tutmasından gelir.

`man passwd` yalnızca ilk bulunanı — bölüm 1'i — gösterir. Dosya biçimini görmek için
bölüm açıkça verilir:

```
$ man 5 passwd | sed -n '1,10p'
PASSWD(5)               File Formats and Configuration               PASSWD(5)

NAME
       passwd - the password file

DESCRIPTION
       /etc/passwd contains one line for each user account, with seven fields
       delimited by colons (":"). These fields are:

       o   login name
```

Sayfa başlığındaki `PASSWD(5)` gösterimi, hangi bölümde olunduğunu her satırda
yineler. Belgelerde `printf(3)` veya `open(2)` gibi yazımlara rastlanır; parantez içindeki
sayı bölüm numarasıdır ve hangi `printf`ten söz edildiğini belirler — kabuk komutu mu,
kütüphane işlevi mi.

Kullanıcı hesabı dosyasının bu bölümdeki tanımı, kullanıcılar ve izinler konusunda
doğrudan kullanılacaktır.

#### Ad Bilinmediğinde Arama

Kılavuz, komutun adı biliniyorsa işe yarar. Ad bilinmiyorsa açıklamalarda arama yapılır:

```
$ man -k 'list directory' | head -3
dir (1)              - list directory contents
ls (1)               - list directory contents
vdir (1)             - list directory contents
```

`man -k` (eşdeğeri `apropos`) tüm kılavuz sayfalarının NAME satırlarında arama yapar.
`man -f` (eşdeğeri `whatis`) ise tam ad eşleşmesi arar. İkisi de önceden hazırlanmış bir
dizine bakar; dizin oluşturulmamışsa sonuç boş döner.

Arama yalnızca tek satırlık açıklamaları tarar, sayfaların tamamını değil. Bu nedenle
sonuç kümesi dar olur ve arama terimi genel tutulmalıdır.

#### Yerleşik Komutların Belgesi

Önceki derste yerleşik komutların ayrı bir program olmadığı görülmüştü. Bunun belgeleme
açısından bir sonucu vardır: yerleşik komutların ayrı kılavuz sayfası yoktur, çünkü ayrı
bir program yoktur. Belgeleri kabuğun kendi sayfasında ve kabuğun `help` yerleşiğindedir.

```
$ help type | sed -n '1,6p'
type: type [-afptP] name [name ...]
    Display information about command type.

    For each NAME, indicate how it would be interpreted if used as a
    command name.

```

Doğru kaynağı seçmek için önce adın türü belirlenir:

```
$ type -t ls cd if
file
builtin
keyword
```

`-t` seçeneği yalnızca türü yazdırır. Üç yanıt üç ayrı yardım kaynağına karşılık gelir:
`file` için `man`, `builtin` için `help`, `keyword` için kabuğun kılavuz sayfası. `if`
bir komut değil, kabuğun dilbilgisine ait bir **anahtar sözcüktür**; denetim yapıları
Kabuk Programlama kursunun konusudur.

#### Belgelerin Sınırı

Kılavuz sayfaları başvuru belgesidir, öğretici değildir. Bir komutun tüm seçeneklerini
eksiksiz sayarlar ama hangi seçeneğin ne zaman kullanılacağını çoğunlukla söylemezler.
Ayrıca belgeler sistemdeki sürüme aittir: bir seçenek kılavuzda yoksa, o sistemde
gerçekten yoktur — başka bir sistemde bulunuyor olması durumu değiştirmez.

Bu iki sınır, kılavuzun ne için kullanılacağını belirler. "Bu komut ne yapar" sorusuna
kılavuz yanıt verir; "bu işi hangi komutla yaparım" sorusuna genellikle vermez. İkinci
soru bu kursun konusudur.

#### Özet

- Kılavuz sayfaları NAME, SYNOPSIS, DESCRIPTION, EXIT STATUS, FILES ve SEE ALSO gibi
  standart alt başlıklar taşır.
- Kullanım özetinde köşeli parantez isteğe bağlılığı, üç nokta yinelenebilirliği, büyük
  harfli adlar yer tutucuyu gösterir.
- Kılavuz numaralı bölümlere ayrılmıştır; aynı ad farklı bölümlerde farklı şeyleri
  anlatır ve `ad(bölüm)` gösterimi hangisinin kastedildiğini belirtir.
- `man -k` açıklama satırlarında arama yapar; adı bilinmeyen komutu bulmanın yoludur.
- Yerleşik komutların ayrı kılavuz sayfası yoktur; `help` ile belgelenirler ve doğru
  kaynak `type -t` ile belirlenir.

#### Sonraki Adım

`type` komutu bir adın karşılığını bulurken belirli bir arama yapar ve önceki derste bir
komut "bulunamadı" hatası verirken de aynı arama başarısız olmuştu. Sonraki ders bu
aramanın kuralını açar: kabuk çalıştırılabilir dosyayı hangi dizinlerde, hangi sırayla
arar, bu sıra nasıl değiştirilir ve neden bulunulan dizin bu listeye eklenmez.

### Komut Yolu

Source: https://academia.sh/tr/kurslar/linuxa-giris/komut-yolu

Çalıştırılabilir arama sırası, ortam değişkenlerinin süreçlere aktarımı, komut karma tablosu ve bulunulan dizinin arama listesine neden eklenmediği.

Önceki derste bir adın türü `type` ile belirlendi ve `file` yanıtı alındığında karşılığın
bir dosya olduğu söylendi. Ancak `ls` yazıldığında tam yol verilmez; kabuk dosyayı bir
yerde **bulur**.

Bu ders o aramanın kuralını açar. Aynı kural, bir komutun neden bulunamadığını, aynı adın
iki farklı programa denk gelebileceğini ve bulunulan dizindeki bir programın neden
doğrudan çalışmadığını birlikte açıklar.

#### Ortam Değişkenleri

Her sürecin, adlarla değerleri eşleyen bir **ortam (environment)** tablosu vardır. Süreç
yeni bir süreç yarattığında bu tablo kopyalanarak aktarılır; çocuk süreç ortamı miras
alır, ancak yaptığı değişiklik ebeveyne geri işlemez.

```
$ env | grep -E '^(HOME|PATH|PWD|SHELL|LANG|LC_ALL)='
PWD=/home/ogrenci
HOME=/home/ogrenci
LC_ALL=C
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

Kabukta tanımlanan her değişken ortama girmez. Sıradan bir atama yalnızca **kabuk
değişkeni** oluşturur; bu değişken çalıştırılan programlara aktarılmaz. Değişkenin ortama
girmesi için `export` ile işaretlenmesi gerekir. Ayrım şudur: kabuk değişkeni kabuğun
kendi belleğindedir, ortam değişkeni çocuk süreçlere kopyalanır.

Bu kursta üç ortam değişkeni doğrudan kullanılır: `HOME` ev dizininin yolunu, `PWD`
çalışma dizinini, `PATH` ise komut arama listesini tutar. `LC_ALL` gibi yerelleştirme
değişkenleri komut çıktılarının dilini ve sıralama düzenini etkiler; bu kursun
çıktıları için standart ayarda tutulmuştur.

#### Arama Sırası

Kabuk bir komut adı gördüğünde sabit bir sırayla karar verir:

1. Ad bir **anahtar sözcük** mü? (`if`, `for`, `while`)
2. Ad bir **takma ad (alias)** mı?
3. Ad bir **kabuk işlevi** mi?
4. Ad bir **yerleşik komut** mu?
5. Değilse `PATH` listesindeki dizinlerde aranır.

İlk dördü kabuğun kendi belleğindedir ve dosya sistemine hiç bakılmaz. Beşinci adım
diskte arama yapar.

`PATH` değişkeni iki nokta üst üste ile ayrılmış dizin yollarından oluşur. Kabuk bu
dizinleri **soldan sağa** tarar ve adı taşıyan, çalıştırma izni olan ilk dosyayı seçer.
Kalan dizinlere bakmaz. Hiçbir dizinde bulunmazsa 127 çıkış durumuyla "command not found"
verir.

Sıranın soldan sağa olması, arama listesindeki konumun bir öncelik anlamına geldiğini
söyler.

#### Gölgeleme

Aynı ad birden çok dizinde bulunabilir. Bu durumda listede önce gelen kazanır ve diğerini
**gölgeler**. Etki, ayrı bir dizin kurularak gösterilebilir:

```
$ mkdir -p /tmp/deneme
$ printf '#!/bin/sh\necho sahte surum\n' > /tmp/deneme/date
$ chmod +x /tmp/deneme/date
$ type -a date
date is /usr/bin/date
date is /bin/date
$ PATH="/tmp/deneme:$PATH"
$ type -a date
date is /tmp/deneme/date
date is /usr/bin/date
date is /bin/date
$ date
sahte surum
```

`type -a` adı taşıyan **tüm** karşılıkları sırayla listeler; ilk satır çalıştırılacak
olandır. Yeni dizin listenin başına eklendiğinde sistemin `date` komutu erişilemez hâle
gelmemiştir — yalnızca arama sırasında sonraya düşmüştür.

Gölgeleme hem bir araç hem bir risktir. Araçtır: bir komutun kendi sürümü, sistem sürümüne
dokunmadan öne alınabilir. Risktir: yazılabilir bir dizin arama listesinin başındaysa, o
dizine dosya yazabilen herkes komut adlarını ele geçirebilir. Bu nedenle arama listesine
eklenen dizinlerin yazma izinleri, izinler konusunda ele alınacak ölçütle
değerlendirilmelidir.

Deneme dizini işi bittiğinde kaldırılır; kalıcı bırakılan böyle bir dizin sonraki
oturumlarda beklenmedik davranışa yol açar.

#### Bulunulan Dizin Listede Değildir

`PATH` içinde bulunulan dizin (`.`) yer almaz. Bunun doğrudan bir sonucu vardır: bir
dizindeki programı çalıştırmak için yol belirtmek gerekir.

```
$ pwd
/home/ogrenci/proje/betik
$ ozet.sh
bash: ozet.sh: command not found
$ echo $?
127
$ ./ozet.sh
ham olcum dosyasi: 0
```

`ozet.sh` ile `./ozet.sh` arasındaki fark, kabuğun bakış açısındandır. Birincisi eğik
çizgi içermeyen bir addır; kabuk onu `PATH` listesinde arar ve bulamaz. İkincisi eğik
çizgi içerir; kabuk bunu bir yol sayar, arama yapmaz ve doğrudan o dosyayı çalıştırır.

Bulunulan dizinin listeye alınmaması bilinçli bir güvenlik kararıdır. Alınsaydı, herkesin
yazabildiği bir dizinde `ls` adında bir dosya bırakmak, o dizine giren herkesin bu dosyayı
çalıştırması için yeterli olurdu. Arama listesi bu nedenle sabit ve denetimli dizinlerden
oluşur.

Bulunulan dizin listeye eklenecekse hiç değilse **sona** eklenir; sistem komutlarını
gölgeleyemeyeceği konum orasıdır.

#### Çalıştırma İzni

Bir dosyanın `PATH` üzerindeki bir dizinde bulunması yetmez; çalıştırılabilir olarak
işaretlenmiş olması gerekir.

```
$ ls -l ozet.sh
-rw-r--r-- 1 ogrenci ogrenci 139 Jul 26 18:49 ozet.sh
$ ./ozet.sh
bash: ./ozet.sh: Permission denied
$ echo $?
126
$ chmod +x ozet.sh
$ ls -l ozet.sh
-rwxr-xr-x 1 ogrenci ogrenci 139 Jul 26 18:49 ozet.sh
$ ./ozet.sh
ham olcum dosyasi: 0
```

İki çıkış durumu ayrı sorunları bildirir: **127** dosya bulunamadı, **126** bulundu ama
çalıştırılamadı. `chmod +x` komutu çalıştırma iznini ekler; izin bitlerinin ne anlama
geldiği ve `-rwxr-xr-x` dizesinin nasıl okunacağı izinler konusunun ilk dersinde
kurulacaktır.

Betiğin ilk satırındaki `#!/bin/sh` gösterimi, dosyanın hangi yorumlayıcıyla
çalıştırılacağını çekirdeğe bildirir. Çekirdek bu satırı okur ve belirtilen programı
çağırıp dosyayı ona argüman olarak verir. Bu nedenle bir kabuk betiği, çalıştırılabilir
ikili dosya olmadığı hâlde doğrudan çalıştırılabilir.

Çıktıda görülen `0` sayısı, ham ölçüm dizininin henüz boş olduğunu bildirir; sonraki konu
bu dizini doldurmakla başlayacaktır.

#### Karma Tablosu

`PATH` her komut için baştan taranırsa, sık kullanılan komutlarda tekrarlanan dizin
okuması olurdu. Kabuk bunu bir **karma tablosunda** bulduğu yolları saklayarak önler.

```
$ PATH="$HOME/proje/betik:$PATH"
$ type ozet.sh
ozet.sh is /home/ogrenci/proje/betik/ozet.sh
$ ozet.sh
ham olcum dosyasi: 0
$ type ozet.sh
ozet.sh is hashed (/home/ogrenci/proje/betik/ozet.sh)
$ hash
hits	command
   2	/home/ogrenci/proje/betik/ozet.sh
$ hash -r
$ type ozet.sh
ozet.sh is /home/ogrenci/proje/betik/ozet.sh
```

İlk çağrıdan sonra `type` yanıtı değişir: yol artık tabloda kayıtlıdır. Bunun bir yan
etkisi vardır — bir program taşındığında veya silindiğinde kabuk eski yolu kullanmayı
sürdürebilir ve "no such file or directory" hatası verebilir. `hash -r` tabloyu temizler
ve aramayı yeniden yaptırır.

Bu davranış, Veri Yapıları kursundaki karma tablosunun tipik bir kullanımıdır:
tekrarlanan pahalı bir aramanın sonucu saklanır, karşılığında saklanan bilginin
eskiyebilme riski kabul edilir.

#### Arama Listesini Kalıcı Genişletmek

Kabukta yapılan `PATH` ataması yalnızca o oturum içindir. Kalıcı olması için, oturum
açılırken okunan bir yapılandırma dosyasına yazılması gerekir:

```
$ tail -2 ~/.profile
PATH="$HOME/proje/betik:$PATH"
export PATH
```

`~/.profile` oturum açılışında okunan kullanıcı yapılandırma dosyasıdır. Yeni bir oturumda
etki görünür:

```
$ echo "$PATH"
/home/ogrenci/proje/betik:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ ozet.sh
ham olcum dosyasi: 0
```

Atamada eski değerin `$PATH` ile korunması önemlidir. `PATH="$HOME/proje/betik"` biçiminde
bir atama listeyi ezerdi ve sistem komutlarının hiçbiri bulunamazdı. Bu, geri dönüşü
zahmetli bir hatadır: hata düzeltilene kadar `ls` dahil çoğu komut çalışmaz, düzeltme için
tam yol yazmak gerekir.

#### Özet

- Kabuk bir adı sırasıyla anahtar sözcük, takma ad, işlev, yerleşik komut olarak arar;
  bulamazsa `PATH` dizinlerini soldan sağa tarar.
- İlk eşleşen dosya kazanır; aynı adın diğer karşılıkları gölgelenir ve `type -a` ile
  görülür.
- Bulunulan dizin `PATH` içinde değildir; oradaki bir programı çalıştırmak için `./`
  öneki gerekir ve bu, yazılabilir dizinlerdeki komut ele geçirmelerine karşı bir
  önlemdir.
- Dosyanın bulunması yetmez; çalıştırma izni yoksa çıkış durumu 126 olur.
- Kabuk bulduğu yolları karma tablosunda saklar; program taşındığında `hash -r` gerekir.
- Kalıcı `PATH` değişikliği oturum açılışında okunan yapılandırma dosyasına yazılır ve
  eski değer korunmalıdır.

#### Sonraki Adım

Sistem tanındı, ağaç kuruldu, betik çalıştı — ama betiğin bildirdiği ölçüm sayısı hâlâ
sıfır. Sonraki konu dosyaların kendisine iner: dizinler arasında nasıl gezinildiği, bir
listeleme çıktısının her sütununun ne anlattığı ve `proje/veri/ham` dizininin nasıl
doldurulacağı ele alınır.

## Dosya ve Dizin İşlemleri

Gezinme, oluşturma, kopyalama, taşıma ve silme; sabit ve sembolik bağlar, arşivleme, sıkıştırma ve dosya aktarımı.

### Gezinme Komutları

Source: https://academia.sh/tr/kurslar/linuxa-giris/gezinme-komutlari

Çalışma dizini değiştirme, listeleme çıktısının sütunlarının tek tek okunması, sıralama ölçütleri ve dosya üstverisinin tamamına erişim.

Önceki konuda `proje/` ağacı kuruldu ve içine bir betik yerleştirildi. Ağaç üzerinde
çalışmadan önce onu **okuyabilmek** gerekir: hangi dosyalar var, ne kadar yer kaplıyorlar,
en son ne zaman değiştiler, kime aitler.

Bu ders listeleme çıktısını sütun sütun çözer. Çıktının okunması, kursun geri kalanında
yapılan her işlemin doğrulama aracıdır; kopyalamanın, taşımanın, bağ kurmanın ve izin
değiştirmenin sonucu hep aynı çıktıda görülecektir.

#### Çalışma Dizini Değiştirme

`cd` komutu çalışma dizinini değiştirir ve dört yaygın biçimde kullanılır:

| Komut | Etki |
|---|---|
| `cd yol` | Belirtilen dizine geçer |
| `cd` | Ev dizinine döner (argümansız) |
| `cd ..` | Bir üst dizine çıkar |
| `cd -` | Bir önceki dizine döner ve adını yazdırır |

Argümansız `cd`, ev dizinini `HOME` ortam değişkeninden okur. Bu, komut yolu dersinde
kurulan ortam kavramının doğrudan bir kullanımıdır: ev dizini kabuğa gömülü bir değer
değil, ortamdan gelen bir ayardır.

#### Varsayılan Listeleme

`ls` komutu argümansız çağrıldığında bulunulan dizini listeler:

```
$ cd proje
$ ls
arsiv  belge  betik  veri
```

Üç davranış varsayılandır: adlar sıralanır, nokta ile başlayanlar gösterilmez ve çıktı
terminal genişliğine göre sütunlara bölünür.

Üçüncüsü, komutun çıktısının nereye gittiğine bağlıdır:

```
$ ls
arsiv  belge  betik  veri
$ ls | cat
arsiv
belge
betik
veri
```

Aynı komut, çıktısı bir terminale gidiyorsa sütunlu, başka bir programa gidiyorsa satır
başına tek ad biçiminde yazar. Bunun nedeni, sütun genişliğinin terminal dışında anlamsız
olmasıdır. Davranış, çıktıyı işleyen betikler için önemlidir: sütunlu biçimi ayrıştırmaya
çalışmak gereksizdir, çünkü betik zaten satır başına tek ad alır.

Nokta ile başlayan adları da görmek için `-a` verilir:

```
$ ls -a betik
.  ..  ozet.sh
```

#### Uzun Listeleme

`-l` seçeneği her dosya için tek satırlık bir üstveri özeti verir:

```
$ ls -l
total 16
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 arsiv
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 belge
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:49 betik
drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 18:47 veri
```

Satırlar yedi alandan oluşur:

**1. Tür ve izinler.** İlk karakter dosya türüdür: `-` sıradan dosya, `d` dizin, `l`
sembolik bağ, `c` karakter aygıtı, `b` blok aygıtı. Kalan dokuz karakter izin bitleridir
ve izinler konusunda ayrıntılı olarak çözülecektir.

**2. Bağlantı sayısı.** Bu dosyaya işaret eden dizin girdisi sayısı. Dizinlerde bu sayı
2'den başlar ve her alt dizin bir artırır: `veri` dizininin `4` değeri, içindeki iki alt
dizinden gelir. Sayının ne anlama geldiği bağlantılar dersinde tam olarak açıklanacaktır.

**3. Sahip kullanıcı.** Dosyanın sahibi.

**4. Sahip grup.** Dosyanın ait olduğu grup.

**5. Boyut.** Sıradan dosyalarda bayt cinsinden içerik boyutu; dizinlerde dizin girdisi
tablosunun kapladığı yer — içindeki dosyaların toplam boyutu **değil**.

**6. Değişiklik zamanı.** İçeriğin son değiştirildiği an. Altı aydan eskiyse saat yerine
yıl gösterilir.

**7. Ad.**

İlk satırdaki `total 16` değeri, listelenen dosyaların kapladığı **blok** sayısıdır;
dosya sayısı veya bayt toplamı değildir. Blok boyutu araca ve sisteme göre değişir,
bu yüzden bu sayı sistemler arasında karşılaştırılmaz.

Boyut sütunu bayt cinsindendir ve büyük dosyalarda okunması zorlaşır:

```
$ ls -l /usr/bin/bash
-rwxr-xr-x 1 root root 1543048 Mar 31  2024 /usr/bin/bash
$ ls -lh /usr/bin/bash
-rwxr-xr-x 1 root root 1.5M Mar 31  2024 /usr/bin/bash
```

`-h` seçeneği boyutu okunabilir birimlere çevirir. Çevrim yuvarlama yapar; kesin bayt
değeri gerektiğinde `-h` kullanılmaz.

#### Dizinin Kendisini Listelemek

Bir dizin adı verildiğinde `ls` dizinin **içeriğini** listeler. Dizinin kendi satırını
görmek için `-d` gerekir:

```
$ ls -ld veri
drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 18:47 veri
```

Bu ayrım, izin ve sahiplik komutlarında sonucun doğrulanması için sürekli kullanılır: bir
dizinin izinleri değiştirildiğinde bakılması gereken satır, içindeki dosyalarınki değil
dizinin kendisininkidir.

Birden çok yol verildiğinde çıktı başlıklarla bölümlenir:

```
$ ls -li betik veri
betik:
total 4
21931 -rwxr-xr-x 1 ogrenci ogrenci 139 Jul 26 18:49 ozet.sh

veri:
total 8
21908 drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 ham
21909 drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 islenmis
```

`-i` seçeneği en sola bir sayı ekler: **düğüm numarası (inode number)**. Bu sayı, dosyanın
üstverisini tutan yapının dosya sistemi içindeki kimliğidir. Adın değil, dosyanın
kimliğidir — bu ayrım bağlantılar dersinin tamamının dayanağıdır.

#### Sıralama

Varsayılan sıralama ada göredir. Değişiklik zamanına göre sıralamak için `-t` kullanılır:

```
$ ls -lt
total 16
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:49 betik
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 arsiv
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 belge
drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 18:47 veri
$ ls -ltr
total 16
drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 18:47 veri
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 belge
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:47 arsiv
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 18:49 betik
```

`-t` en yeniyi başa alır; `-r` sırayı ters çevirir. `-ltr` bileşimi en yeniyi **sona**
alır ve uzun listelerde en çok kullanılan biçimdir: son değişen dosya, ekranı kaydırmaya
gerek kalmadan en altta görünür.

Eşit zamanlı dosyalarda ikincil ölçüt addır; bu, çıktının aynı girdi için kararlı
kalmasını sağlar.

Diğer sık kullanılan sıralamalar `-S` (boyuta göre, büyükten küçüğe) ve `-X` (uzantıya
göre) seçenekleridir.

#### Üstverinin Tamamı

`ls -l` üstverinin bir özetidir. Tamamı `stat` ile okunur:

```
$ stat betik/ozet.sh
  File: betik/ozet.sh
  Size: 139       	Blocks: 8          IO Block: 4096   regular file
Device: 0,71	Inode: 21931       Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1001/ ogrenci)   Gid: ( 1001/ ogrenci)
Access: 2026-07-26 18:49:26.461777000 +0000
Modify: 2026-07-26 18:49:26.458777000 +0000
Change: 2026-07-26 18:49:26.460777000 +0000
 Birth: 2026-07-26 18:49:26.458777000 +0000
```

Çıktı, `ls -l`'de gizli kalan üç bilgiyi açar.

**İzinler iki biçimde birden verilir:** `0755` ve `-rwxr-xr-x`. Aynı değerin sekizlik ve
harfli gösterimleridir; aralarındaki dönüşüm izin bitleri dersinin konusudur.

**Kullanıcı ve grup sayısal kimlikleriyle birlikte gösterilir:** `1001/ogrenci`. Sistemin
sakladığı değer sayıdır; ad, bir eşleme dosyasından çözülür.

**Üç ayrı zaman damgası vardır:**

- **Access** — içeriğin son okunduğu an
- **Modify** — içeriğin son değiştirildiği an; `ls -l` bu değeri gösterir
- **Change** — üstverinin son değiştiği an; izin veya sahiplik değişikliği bunu günceller,
  içeriği değiştirmez

Üçüncüsü sık karıştırılır. Bir dosyanın izinleri değiştirildiğinde `ls -lt` sıralaması
değişmez, çünkü değişen zaman `Modify` değil `Change`'dir. Bu ayrım, "dosyaya
dokunulmuş mu" sorusunun yanıtını değiştirir.

`Blocks` alanı ayrılan blok sayısını verir ve `Size` ile orantılı olmak zorunda değildir:
139 baytlık bir dosya, blok boyutu nedeniyle diskte daha fazla yer kaplar.

`stat` POSIX'te tanımlı değildir ve çıktı biçimi araç ailesine göre değişir. Biçimlendirme
seçeneği GNU araçlarında `-c`, BSD araçlarında `-f`'dir; taşınabilir olması gereken
betiklerde `stat` yerine `ls` çıktısı veya `find` ölçütleri tercih edilir.

#### Özet

- `ls` varsayılan olarak adları sıralar, gizli dosyaları atlar ve çıktısı terminale
  gidiyorsa sütunlara böler.
- Uzun listeleme yedi alan verir: tür ve izinler, bağlantı sayısı, sahip, grup, boyut,
  değişiklik zamanı, ad.
- Dizinlerde boyut sütunu dizin girdisi tablosunun büyüklüğüdür; içeriğin toplamı değildir.
- `-d` dizinin kendi satırını, `-i` düğüm numarasını gösterir; düğüm numarası adın değil
  dosyanın kimliğidir.
- `-t` değişiklik zamanına göre sıralar, `-r` ters çevirir; `-ltr` en yeniyi sona alır.
- Üstveride üç zaman damgası vardır: erişim, içerik değişikliği ve üstveri değişikliği.

#### Sonraki Adım

Ağaç okunabiliyor ama hâlâ boş: `ham` dizininde tek bir ölçüm dosyası yok. Sonraki ders
dosya oluşturma, kopyalama ve taşıma işlemlerini ele alır; bu üç işlemin dosya sistemi
düzeyinde neden bambaşka maliyetlere sahip olduğunu ve hangi durumda sessizce veri
kaybettirdiklerini gösterir.

### Oluşturma, Kopyalama ve Taşıma

Source: https://academia.sh/tr/kurslar/linuxa-giris/olusturma-kopyalama-tasima

Dosya oluşturma ve zaman damgası ayarlama, kopyalamanın üstüne yazma davranışı, hedefin dizin olması durumu ve taşımanın dosya sistemi düzeyindeki anlamı.

Önceki ders ağacı okunabilir kıldı ama `veri/ham` dizini boştu. Bu ders ağacı doldurur:
ölçüm dosyaları oluşturulur, işlenmiş kopyaları üretilir ve bir yedek dizini kurulur.

Üç komut kullanılacak — `touch`, `cp`, `mv` — ve üçünün de sessizce veri kaybettirdiği
durumlar vardır. Bu durumların hangi kurallardan doğduğu, komutların kendisinden daha
önemlidir.

#### Dosya Oluşturma ve Zaman Damgaları

`touch` komutunun asıl işi zaman damgası ayarlamaktır; var olmayan bir dosya adı
verildiğinde onu boş olarak oluşturması ikincil bir davranıştır.

```
$ touch veri/ham/olcum-01.csv
$ ls -l veri/ham
total 0
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:02 olcum-01.csv
```

Boyut sıfırdır: dosya vardır ama içeriği yoktur. Dosyanın var olması ile içeriğinin olması
ayrı şeylerdir; bir dizin girdisi ve bir düğüm oluşturulmuştur, veri bloğu ayrılmamıştır.

İçerik yazmak için çıktı yönlendirme kullanılır:

```
$ printf 'zaman,sicaklik,nem\n08:00,21.4,55\n12:00,24.9,49\n' > veri/ham/olcum-01.csv
$ cat veri/ham/olcum-01.csv
zaman,sicaklik,nem
08:00,21.4,55
12:00,24.9,49
```

`>` işareti komutun çıktısını terminale değil dosyaya yazdırır. Yönlendirmenin dilbilgisi
Kabuk Programlama kursunun konusudur; burada yalnızca dosya üretmek için kullanılmıştır.
Dikkat edilecek nokta şudur: `>` hedef dosyayı **uyarmadan boşaltır**. Var olan bir dosyaya
`>` ile yazmak, eski içeriği geri alınamaz biçimde siler.

Aynı biçimde iki ölçüm dosyası daha oluşturulur:

```
$ printf 'zaman,sicaklik,nem\n08:00,19.8,61\n12:00,23.1,52\n' > veri/ham/olcum-02.csv
$ printf 'zaman,sicaklik,nem\n08:00,22.6,58\n12:00,26.3,44\n' > veri/ham/olcum-03.csv
$ ls -l veri/ham
total 12
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:02 olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-02.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-03.csv
```

Var olan bir dosyada `touch` içeriğe dokunmaz, yalnızca zaman damgalarını o ana ayarlar.
Belirli bir zamana ayarlamak için `-t` seçeneği kullanılır:

```
$ touch /tmp/ornek.txt
$ ls -l /tmp/ornek.txt
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:03 /tmp/ornek.txt
$ touch -t 202603110930 /tmp/ornek.txt
$ ls -l /tmp/ornek.txt
-rw-r--r-- 1 ogrenci ogrenci 0 Mar 11 09:30 /tmp/ornek.txt
```

`-t` değeri `YYYYMMDDhhmm` biçimindedir ve POSIX'te tanımlıdır. GNU araçlarındaki `-d`
seçeneği okunabilir tarih dizeleri kabul eder ama taşınabilir değildir; betiklerde `-t`
tercih edilir.

Zaman damgası ayarlamak yalnızca bir düzen işi değildir: yedekleme ve derleme araçlarının
çoğu "kaynak hedeften yeni mi" karşılaştırması yapar ve bu karşılaştırma değişiklik
zamanına dayanır.

#### Kopyalama

`cp` komutu iki argüman alır: kaynak ve hedef. Hedefin ne olduğuna göre iki farklı kural
işler.

**Hedef var olan bir dizinse**, kaynak o dizinin içine, **aynı adla** kopyalanır:

```
$ cp veri/ham/olcum-01.csv veri/islenmis/
$ ls -l veri/islenmis
total 4
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-01.csv
```

**Hedef bir dizin değilse**, kaynak o adla kopyalanır:

```
$ cp veri/ham/olcum-01.csv veri/islenmis/ozet-01.csv
$ ls -l veri/islenmis
total 8
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 ozet-01.csv
```

Bu iki kural, en sık yapılan hatanın kaynağıdır: hedef dizinin adı yanlış yazılırsa dizin
bulunamaz ve komut, kopyayı **o yanlış adla bir dosya** olarak oluşturur. Hata iletisi
gelmez. Hedefin sonuna eğik çizgi koymak bu hatayı yakalar: `hedefdizin/` yazıldığında ve
böyle bir dizin yoksa komut hata verir.

#### Üstüne Yazma Sessizdir

`cp` varsayılan olarak hedefin üzerine sormadan yazar:

```
$ cat veri/islenmis/ozet-01.csv
zaman,sicaklik,nem
08:00,21.4,55
12:00,24.9,49
$ cp veri/ham/olcum-02.csv veri/islenmis/ozet-01.csv
$ cat veri/islenmis/ozet-01.csv
zaman,sicaklik,nem
08:00,19.8,61
12:00,23.1,52
```

Eski içerik gitmiştir ve geri getirilemez. Uyarı yoktur, çıkış durumu sıfırdır.

`-i` seçeneği üstüne yazmadan önce sorar:

```
$ cp -i veri/ham/olcum-03.csv veri/islenmis/ozet-01.csv
cp: overwrite 'veri/islenmis/ozet-01.csv'? n
```

Olumsuz yanıtta dosya değişmez ve komut sıfırdan farklı bir çıkış durumu döndürür. `-i`
POSIX'te tanımlıdır ve etkileşimli kullanımda önerilen alışkanlıktır.

Var olan hedefi hiç sormadan koruma seçeneği de vardır, ancak taşınabilir değildir; GNU
araçlarında `-n` kullanımdan kaldırılmaya adaydır ve bir dosyayı atladığında o dosyayı
adıyla bildiren bir tanı yazdırıp sıfırdan farklı bir çıkış durumu döndürür. Betiklerde
hedefin varlığı önce sınanır, seçeneğe güvenilmez.

#### Dizin Kopyalama

Dizinler varsayılan olarak kopyalanmaz; özyinelemeli kopyalama için `-r` gerekir.

```
$ cp -r veri/ham arsiv/ham-yedek
$ ls -l arsiv/ham-yedek
total 12
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:04 olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:04 olcum-02.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:04 olcum-03.csv
```

Kopyalar yeni dosyalardır: yeni düğüm, yeni zaman damgası. Zaman damgalarının korunması
isteniyorsa `-p` eklenir:

```
$ cp -rp veri/ham arsiv/ham-p
$ ls -l arsiv/ham-p
total 12
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:02 olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-02.csv
-rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-03.csv
```

İki listeleme karşılaştırıldığında fark açıktır: `-p` olmadan tüm dosyalar kopyalama anını
taşır, `-p` ile özgün zamanlarını korurlar. `-p` ayrıca izinleri ve sahipliği de
korumaya çalışır. Yedeklemede bu ayrıntı belirleyicidir; zaman damgası kaybolan bir yedek,
"hangi sürüm daha yeni" sorusuna yanıt veremez.

Dizin kopyalamada hedef kuralı bir tuzağa dönüşür:

```
$ cp -r /tmp/dnm/kaynak /tmp/dnm/hedef
$ find /tmp/dnm | sort
/tmp/dnm
/tmp/dnm/hedef
/tmp/dnm/hedef/kaynak
/tmp/dnm/hedef/kaynak/a.txt
/tmp/dnm/kaynak
/tmp/dnm/kaynak/a.txt
```

Hedef dizin **zaten varsa** kaynak onun içine yerleşir. Aynı komut ikinci kez
çalıştırıldığında sonuç değişmez, çünkü `hedef/kaynak` de artık vardır ve içerik üzerine
yazılır. Ancak hedef yokken çalıştırılırsa hedef, kaynağın kopyası olarak oluşturulur. Aynı
komutun iki farklı sonuç vermesi, hedefin önceden var olup olmamasına bağlıdır.

#### Taşıma

`mv` yüzeyde kopyalama gibi görünür ama dosya sistemi düzeyinde bambaşka bir işlemdir.

```
$ ls -li veri/islenmis
total 8
22212 -rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-01.csv
22545 -rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 ozet-01.csv
$ mv veri/islenmis/ozet-01.csv veri/islenmis/gunluk-ozet.csv
$ ls -li veri/islenmis
total 8
22545 -rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 gunluk-ozet.csv
22212 -rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 olcum-01.csv
```

Düğüm numarası değişmemiştir: `22545` hem eski hem yeni adda aynıdır. Değişen tek şey
**dizin girdisidir**. Ad, dosyanın bir özelliği değil, dizinde tutulan bir eşlemedir; adı
değiştirmek dosyaya dokunmaz.

Bunun ölçülebilir sonucu şudur: aynı dosya sistemi içinde taşıma, dosya boyutundan
bağımsız olarak sabit maliyetlidir. Bir baytlık dosya ile bir gigabaytlık dosyayı yeniden
adlandırmak aynı süreyi alır, çünkü hiçbir veri okunmaz veya yazılmaz.

Aynı işlem farklı dosya sistemleri arasında yapıldığında bu geçerli değildir. Düğüm
numaraları yalnızca kendi dosya sistemi içinde anlamlıdır; bir aygıttan diğerine girdi
taşınamaz. Bu durumda `mv` içeriği kopyalar ve kaynağı siler — süre dosya boyutuyla
orantılıdır ve işlem yarıda kesilirse hedef eksik kalabilir.

Hedef bir dizinse `mv` de aynı adlandırma kuralını izler:

```
$ mv veri/islenmis/olcum-01.csv belge/
$ ls belge
olcum-01.csv
$ ls veri/islenmis
gunluk-ozet.csv
```

`mv` de üstüne sessizce yazar ve `-i` seçeneğiyle sorması sağlanır. Kopyalamadan farklı
olarak burada iki dosya birden kaybedilir: hedefin eski içeriği silinir ve kaynak da
ortadan kalkar.

#### Özet

- `touch` zaman damgası ayarlar; var olmayan dosyayı boş olarak oluşturması ikincil bir
  davranıştır ve `-t` ile belirli bir zaman verilebilir.
- Kopyalamada hedef var olan bir dizinse kaynak aynı adla içine, değilse verilen adla
  kopyalanır; yanlış yazılmış dizin adı sessizce bir dosya oluşturur.
- `cp` ve `mv` hedefin üzerine sormadan yazar; `-i` sormayı sağlar.
- Dizin kopyalama `-r` ister; `-p` zaman damgalarını, izinleri ve sahipliği korur.
- Aynı dosya sistemi içinde taşıma yalnızca dizin girdisini değiştirir: düğüm numarası
  korunur ve maliyet dosya boyutundan bağımsızdır.
- Farklı dosya sistemleri arasında taşıma kopyala-ve-sil işlemine dönüşür; maliyet boyutla
  orantılıdır ve yarıda kesilme riski taşır.

#### Sonraki Adım

Bu dersin üç komutu da veri kaybettirebilir, ama hepsi bir şeyin üzerine yazarak yapar.
Silme komutu ise doğrudan yok eder ve dosya sisteminde bir "geri al" işlemi yoktur. Sonraki
ders silmenin çekirdek düzeyinde ne anlama geldiğini, hangi durumda silinen bir dosyanın
hâlâ yaşadığını ve yıkıcı komutları çalıştırmadan önce doğrulamanın nasıl alışkanlık
hâline getirileceğini ele alır.

### Silme ve Geri Alınamazlık

Source: https://academia.sh/tr/kurslar/linuxa-giris/silme-ve-geri-alinamazlik

Silmenin bağ koparma olarak tanımı, açık dosya tanıtıcılarının etkisi, yıkıcı komutlarda doğrulama alışkanlıkları ve tire ile başlayan dosya adlarının tehlikesi.

Önceki dersin komutları veri kaybettirebiliyordu, ama hepsi bir şeyin üzerine yazarak.
Silme doğrudan yok eder ve dosya sisteminde bir "geri al" işlemi yoktur: komut satırından
silinen dosya bir çöp kutusuna gitmez.

Bu ders önce silmenin çekirdek düzeyinde ne olduğunu tanımlar — tanım, silinen bir
dosyanın neden bazen hâlâ okunabildiğini açıklar — sonra yıkıcı komutlarda uygulanacak
doğrulama alışkanlıklarını kurar.

#### Silmek Bağ Koparmaktır

`rm` komutunun yaptığı işlem, adından anlaşılandan dardır: **dizin girdisini kaldırır**.
İşlemin sistem çağrısı düzeyindeki adı `unlink`, yani "bağı kopar"dır.

Her dosyanın üstverisinde bir **bağlantı sayısı** tutulur; bu, dosyaya işaret eden dizin
girdisi sayısıdır. `rm` bu sayıyı bir azaltır. Veri blokları ancak iki koşul birden
sağlandığında serbest bırakılır:

1. Bağlantı sayısı sıfıra düşmüştür.
2. Dosyayı açık tutan hiçbir süreç kalmamıştır.

İkinci koşul doğrudan gösterilebilir:

```
$ printf 'gecici veri\n' > /tmp/gecici.txt
$ exec 3< /tmp/gecici.txt
$ rm /tmp/gecici.txt
$ ls -l /tmp/gecici.txt
ls: cannot access '/tmp/gecici.txt': No such file or directory
$ cat <&3
gecici veri
$ exec 3<&-
```

Dosya silinmiştir: adı dizinde yoktur, listeleme hata verir. Yine de içeriği okunabilmiştir,
çünkü bir **dosya tanıtıcısı (file descriptor)** onu açık tutmaktadır. Tanıtıcı kapandığı
anda veri gerçekten serbest kalır.

Bu davranışın iki pratik sonucu vardır. Birincisi, çalışan bir programın kütük dosyası
silindiğinde program yazmayı sürdürür ve disk alanı geri kazanılmaz; alan ancak program
yeniden başlatıldığında boşalır. İkincisi, bir programın kullandığı dosyayı silmek onu
çökertmez — program dosyayı adıyla değil tanıtıcısıyla kullanır.

Bağlantı sayısı birden büyükse silme veriye hiç dokunmaz; yalnızca adlardan biri gider.
Bunun nasıl mümkün olduğu sonraki dersin konusudur.

#### Dizin Silme

Dizinler iki komutla silinir ve ikisi arasındaki fark bir güvenlik ölçütüdür.

`rmdir` yalnızca **boş** dizinleri siler:

```
$ ls arsiv
ham-p  ham-yedek
$ rmdir arsiv/ham-p
rmdir: failed to remove 'arsiv/ham-p': Directory not empty
```

`rm -r` dizini içeriğiyle birlikte, özyinelemeli olarak siler:

```
$ rm -r arsiv/ham-p
$ ls arsiv
ham-yedek
```

Önceki derste `-p` seçeneğinin etkisini göstermek için oluşturulan ikinci yedek böylece
kaldırıldı; `ham-yedek` dizini kalmaya devam ediyor.

`rmdir` başarısızlığı bir kusur değil, bir özelliktir: dizinin boş olmadığını
bildirdiğinde, silinmesi düşünülmemiş içeriğin varlığını haber verir. Bir dizinin
boşaltıldığını doğrulamak için `rmdir` kullanmak, `rm -r` kullanmaktan güvenlidir.

#### `-f` Ne Yapar, Ne Yapmaz

`rm` var olmayan bir dosya için hata verir ve sıfırdan farklı bir durumla döner:

```
$ rm /tmp/dnm2/yok.txt
rm: cannot remove '/tmp/dnm2/yok.txt': No such file or directory
$ echo $?
1
$ rm -f /tmp/dnm2/yok.txt
$ echo $?
0
```

`-f` seçeneği iki şey yapar: var olmayan dosyalar için hata vermez ve onay sormaz. Silme
gücünü artırmaz — silinemeyen bir dosyayı silmez, izinler yine de geçerlidir.

Betiklerde `-f` sık kullanılır çünkü "zaten yoksa sorun değil" davranışı gerekir. Ancak
onay sorularını da kapattığı için, `-r` ile birleştiğinde en tehlikeli biçime dönüşür.

#### Doğrulama Alışkanlıkları

Kabuk dersinde kurulan bir olgu burada güvenlik aracına dönüşür: açılımları yapan
kabuktur, komut yalnızca sonucu görür. Öyleyse sonuç, komut çalıştırılmadan
görülebilir.

```
$ echo veri/ham/*.csv
veri/ham/olcum-01.csv veri/ham/olcum-02.csv veri/ham/olcum-03.csv
$ echo rm veri/ham/*.csv
rm veri/ham/olcum-01.csv veri/ham/olcum-02.csv veri/ham/olcum-03.csv
```

İkinci satır, çalıştırılacak komutun tam hâlidir. Silme komutunun başına `echo` yazıp
çıktıyı okumak, deseni yanlış yazmanın bedelini ödemeden hatayı görmeyi sağlar. Yıkıcı bir
komutu bu biçimde bir kez çalıştırmak, alışkanlık hâline getirilmesi gereken tek
adımlık bir denetimdir.

Deseni `ls` ile sınamak da aynı işi görür ve dosyaların gerçekten var olduğunu doğrular.

Kabuğun boşlukla bölme kuralı burada kritik hâle gelir. `rm veri/ham/*.csv` yerine yanlışlıkla
`rm veri/ham/* .csv` yazılırsa — yıldız ile nokta arasında bir boşluk — desen tüm dosyalarla
eşleşir ve dizin boşalır. İki komut arasındaki fark tek bir boşluktur; `echo` ile ön
denetim, bu farkı sonuç doğurmadan gösterir.

`rm` etkileşimli kullanımda iki onay seçeneği sunar:

```
$ rm -i normal.txt
rm: remove regular empty file 'normal.txt'? n
$ rm -I *.txt
rm: remove 5 arguments? n
```

`-i` her dosya için ayrı ayrı sorar ve POSIX'te tanımlıdır. `-I` yalnızca üçten çok dosya
verildiğinde veya `-r` kullanıldığında bir kez sorar; GNU araçlarına özgüdür ve BSD
araçlarında bulunmaz. `-I` uygulamada daha kullanışlıdır: her dosyada soru sorulması
kullanıcıyı otomatik "evet" demeye alıştırır, tek soru ise gerçekten okunur.

#### Tire ile Başlayan Adlar

Kabuk dersinde tanıtılan `--` ayıracının neden gerekli olduğu burada görünür:

```
$ ls
-kayit.txt  normal.txt
$ rm -kayit.txt
rm: invalid option -- 'k'
Try 'rm ./-kayit.txt' to remove the file '-kayit.txt'.
Try 'rm --help' for more information.
$ rm -- -kayit.txt
$ ls
normal.txt
```

Komut, tire ile başlayan argümanı seçenek sanmıştır. `--` ayıracından sonrası her zaman
dosya adı olarak yorumlanır; `./` öneki de aynı işi görür çünkü ad artık tire ile başlamaz.

Bu, teorik bir sorun değildir. Bir desenin böyle bir adla eşleşmesi, komutun beklenmedik
seçeneklerle çalışmasına yol açabilir. Betiklerde kullanıcıdan gelen dosya adları her zaman
`--` ayıracından sonra verilmelidir.

#### En Yıkıcı Biçim

`rm -rf` bileşimi, verilen yolun altındaki her şeyi sormadan ve hata bildirmeden siler.
Kök dizin üzerinde çalıştırıldığında sistemin tamamını hedefler.

Bu komut bu derste **çalıştırılmamıştır** ve denenmemelidir. Yaygın araç
gerçekleştirimlerinde kök dizin için bir koruma vardır ve komut reddedilir, ancak koruma
bir seçenekle devre dışı bırakılabilir ve her sistemde bulunmaz. Asıl tehlike kökün
kendisinde de değildir: değişkenin boş kalması durumunda `rm -rf "$dizin"/` gibi bir satır
kök dizini hedef alır.

Uygulamada üç alışkanlık bu sınıf hataların çoğunu önler:

**Mutlak yol yerine dizine girip göreli yolla çalışmak.** Yanlış dizindeyken komut ya hata
verir ya da dar bir alanı etkiler.

**Değişkenli yollarda `rm` yerine önce `echo` çalıştırmak.** Değişken boşsa bu, çıktıda
hemen görünür.

**Silmek yerine taşımak.** Silinecek içeriği önce bir kenara taşımak, kararın geri
alınabilir kalmasını sağlar; taşınan dizin bir süre sonra bilinçli olarak silinir.

Silinen veriyi geri getirmenin sistem düzeyindeki tek güvenilir yolu yedektir. Yedekleme
ve anlık görüntü stratejileri Sistem Yönetimi kursunun konusudur; bu kursun kapsamında
geri alma yoktur.

#### Özet

- Silme dizin girdisini kaldırır ve bağlantı sayısını azaltır; veri, sayı sıfırlanana ve
  dosyayı açık tutan süreç kalmayana kadar serbest bırakılmaz.
- `rmdir` yalnızca boş dizinleri siler ve bu başarısızlık bir güvenlik ölçütüdür; `rm -r`
  içeriğiyle birlikte siler.
- `-f` onay sormayı ve var olmayan dosya hatasını kapatır; silme yetkisi kazandırmaz.
- Yıkıcı bir komutun başına `echo` yazmak, kabuğun üreteceği argüman listesini sonuç
  doğurmadan gösterir.
- `-i` her dosyada, `-I` toplu işlemde bir kez sorar; `-I` taşınabilir değildir.
- Tire ile başlayan dosya adları seçenek sanılır; `--` ayıracı veya `./` öneki bunu
  giderir.

#### Sonraki Adım

Silmenin tanımı bir soruyu açıkta bıraktı: bağlantı sayısı nasıl birden büyük olabilir,
yani bir dosyanın birden çok adı nasıl olur? Sonraki ders bu soruyu yanıtlar ve iki farklı
bağlantı türünü — aynı düğümü paylaşan sabit bağ ile bir yol dizesi tutan sembolik bağ —
karşılaştırır.

### Bağlantılar

Source: https://academia.sh/tr/kurslar/linuxa-giris/baglantilar

Dizin girdisi ile düğüm ayrımı, sabit bağın aynı düğümü paylaşması, sembolik bağın yol dizesi tutması ve iki türün kısıtlarının karşılaştırılması.

Önceki ders silmeyi "bağ koparmak" olarak tanımladı ve bir dosyanın birden çok adı
olabileceğini söyleyerek bitti. Bu ders o olasılığı kurar.

Dayanak, gezinme dersinde tanıtılan ayrımdır: **dizin girdisi** bir adı bir düğüme
eşler, **düğüm (inode)** ise dosyanın üstverisini ve veri bloklarının yerini tutar. Ad
düğümün içinde saklanmaz. Öyleyse birden çok girdinin aynı düğümü göstermesini engelleyen
bir şey yoktur.

#### Sabit Bağ

**Sabit bağ (hard link)**, var olan bir düğüme yeni bir dizin girdisi eklemektir.

```
$ ln veri/ham/olcum-03.csv veri/son-olcum.csv
$ ls -li veri/ham/olcum-03.csv veri/son-olcum.csv
22143 -rw-r--r-- 2 ogrenci ogrenci 47 Jul 26 19:03 veri/ham/olcum-03.csv
22143 -rw-r--r-- 2 ogrenci ogrenci 47 Jul 26 19:03 veri/son-olcum.csv
```

İki satırda da düğüm numarası `22143`'tür ve bağlantı sayısı sütunu `1`'den `2`'ye
çıkmıştır. Bu bir kopya değildir: tek bir dosya ve iki adı vardır. Diskte ek yer
kullanılmamıştır; yalnızca bir dizin girdisi eklenmiştir.

İki ad arasında **hiyerarşi yoktur**. Hangisinin "asıl" olduğu sorusu anlamsızdır; ikisi de
aynı düğüme eşit uzaklıktadır. Bunun sonucu silmede görünür:

```
$ rm veri/ham/olcum-03.csv
$ ls -li veri/son-olcum.csv
22143 -rw-r--r-- 1 ogrenci ogrenci 47 Jul 26 19:03 veri/son-olcum.csv
$ cat veri/son-olcum.csv
zaman,sicaklik,nem
08:00,22.6,58
12:00,26.3,44
```

Adlardan biri silinmiş, bağlantı sayısı `1`'e düşmüş, veri yerinde kalmıştır. Önceki
dersteki kural burada doğrulanır: veri blokları ancak bağlantı sayısı sıfırlandığında
serbest bırakılır.

Silinen ad geri konabilir, çünkü düğüm hâlâ erişilebilirdir:

```
$ ln veri/son-olcum.csv veri/ham/olcum-03.csv
$ ls -li veri/ham/olcum-03.csv veri/son-olcum.csv
22143 -rw-r--r-- 2 ogrenci ogrenci 47 Jul 26 19:03 veri/ham/olcum-03.csv
22143 -rw-r--r-- 2 ogrenci ogrenci 47 Jul 26 19:03 veri/son-olcum.csv
```

#### Sabit Bağın İki Kısıtı

Sabit bağların iki kısıtı vardır ve ikisi de düğüm kavramının doğrudan sonucudur.

**Dosya sistemi sınırını geçemez.** Düğüm numarası yalnızca kendi dosya sistemi içinde
anlamlıdır; başka bir dosya sistemindeki düğüme girdi yazılamaz.

```
$ ln veri/ham/olcum-01.csv /dev/shm/olcum-01.csv
ln: failed to create hard link '/dev/shm/olcum-01.csv' => 'veri/ham/olcum-01.csv': Invalid cross-device link
```

Bu, taşıma dersindeki gözlemin aynı kökten gelen ikizidir: aynı dosya sistemi içinde taşıma
ucuzdur, dışına taşıma kopyalamaya dönüşür. Her ikisinin de nedeni, dizin girdisinin
yalnızca kendi dosya sistemindeki düğümlere işaret edebilmesidir.

**Dizinlere kurulamaz.**

```
$ ln veri/ham veri/ham-bag
ln: veri/ham: hard link not allowed for directory
```

Yasak, dosya sistemini ağaç olarak tutmak içindir. Dizinlere sabit bağ kurulabilseydi
döngüler oluşabilir ve ağacı dolaşan her araç sonsuz özyinelemeye girebilirdi. Yasağın
tek istisnası, sistemin kendi kurduğu iki girdidir:

```
$ ls -lid veri/. veri/ham/..
21906 drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 19:08 veri/.
21906 drwxr-xr-x 4 ogrenci ogrenci 4096 Jul 26 19:08 veri/ham/..
```

`veri/.` ile `veri/ham/..` aynı düğümü gösterir: ikisi de `veri` dizininin kendisidir.
Bu, gezinme dersinde açıklanmadan bırakılan bir sayıyı da açıklar. Bir dizinin bağlantı
sayısı şunlardan oluşur: üst dizindeki adı, kendi `.` girdisi ve her alt dizinin `..`
girdisi. `veri` dizininin iki alt dizini olduğu için sayı $1 + 1 + 2 = 4$'tür.

#### Sembolik Bağ

**Sembolik bağ (symbolic link)** bambaşka bir nesnedir: kendi düğümü olan, içeriği bir
**yol dizesinden** ibaret küçük bir dosyadır. Çekirdek bu dosyayı okuduğunda içindeki yolu
çözümlemeye devam eder.

Ölçüm dizinindeki en son dosyaya sabit adla erişmek için sembolik bağ uygundur:

```
$ ln -s ham/olcum-03.csv veri/guncel.csv
$ ls -li veri
total 8
28322 lrwxrwxrwx 1 ogrenci ogrenci   16 Jul 26 19:08 guncel.csv -> ham/olcum-03.csv
21908 drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 19:07 ham
21909 drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 19:03 islenmis
```

Çıktıda dört ayrıntı vardır. Tür karakteri `l`'dir. Düğüm numarası hedefinkinden
farklıdır — ayrı bir dosyadır. Boyut `16`'dır; bu, hedefin içeriğinin değil, `ham/olcum-03.csv`
dizesinin uzunluğudur. İzin bitleri `rwxrwxrwx` görünür ve anlamsızdır: erişim denetimi
hedefin izinlerine göre yapılır.

Hedef `readlink` ile okunur, içerik ise doğrudan erişilir:

```
$ readlink veri/guncel.csv
ham/olcum-03.csv
$ cat veri/guncel.csv
zaman,sicaklik,nem
08:00,22.6,58
12:00,26.3,44
```

Çoğu komut sembolik bağı **izler**: `cat` bağı değil hedefi okur. Bağın kendisiyle
ilgilenen komutlar (`rm`, `mv`, `ls -l`) ise izlemez. `rm guncel.csv` bağı siler, hedefe
dokunmaz.

#### Göreli Hedef Hangi Dizine Göredir

Sembolik bağın içindeki yol göreli olabilir. Bu durumda çözümleme, komutun çalıştırıldığı
dizine göre değil, **bağın bulunduğu dizine** göre yapılır.

Yukarıdaki bağ `veri/` içinde durur ve hedefi `ham/olcum-03.csv`'dir; çözümleme
`veri/ham/olcum-03.csv` verir. Aynı bağ farklı bir dizinde oluşturulsaydı hedef
bulunamazdı:

```
$ ln -s veri/ham/olcum-01.csv /dev/shm/olcum-01.csv
$ ls -l /dev/shm/olcum-01.csv
lrwxrwxrwx 1 ogrenci ogrenci 21 Jul 26 19:08 /dev/shm/olcum-01.csv -> veri/ham/olcum-01.csv
$ cat /dev/shm/olcum-01.csv
cat: /dev/shm/olcum-01.csv: No such file or directory
```

Bağ oluşturulmuştur — hedefin var olup olmadığı denetlenmez — ama çözümlenemez. `/dev/shm`
içinde `veri/ham` diye bir yol yoktur. Bu duruma **kırık bağ (dangling link)** denir.

Kırık bağ bir hata değil, tanımın doğal sonucudur: sembolik bağ bir yol dizesidir, hedefe
bir tutamak değildir. Hedef silinirse, taşınırsa veya bağ başka bir yere kopyalanırsa bağ
kırılır.

Seçim ölçütü buradan çıkar. Göreli hedef, bağla hedefi birlikte taşınabilir kılar: tüm ağaç
başka bir yere kopyalandığında bağ çalışmayı sürdürür. Mutlak hedef ise bağ nereye giderse
gitsin aynı dosyayı gösterir, ama ağaç taşındığında kırılır. Ağaç içi bağlarda göreli,
sistem genelindeki sabit konumlara yapılan bağlarda mutlak hedef tercih edilir.

#### İki Türün Karşılaştırması

| Ölçüt | Sabit bağ | Sembolik bağ |
|---|---|---|
| Ne tutar | Aynı düğüme ikinci girdi | Hedefin yol dizesi |
| Kendi düğümü | Yok | Var |
| Dosya sistemi sınırı | Geçemez | Geçer |
| Dizine kurulabilir | Hayır | Evet |
| Hedef silinince | Veri yaşar, sayı azalır | Bağ kırılır |
| Ayırt edilmesi | `ls -i` ile aynı numara | `ls -l` çıktısında `l` ve `->` |

Kullanım ayrımı basit bir soruya indirgenir: aynı veriye ikinci bir ad mı gerekiyor, yoksa
değişebilen bir hedefe sabit bir işaret mi? Birinci durumda sabit bağ, ikinci durumda
sembolik bağ kullanılır. Proje ağacındaki `guncel.csv`, ikinci duruma örnektir: yeni bir
ölçüm dosyası geldiğinde bağın hedefi değiştirilir, bağın adı sabit kalır.

Sistem yerleşiminde de aynı yaklaşım görülür. Dizin hiyerarşisi dersindeki
`/bin -> usr/bin` bağı, eski yolun çalışmayı sürdürmesini sağlayan sembolik bir bağdır — dizine
kurulduğu için sabit bağ olamazdı.

#### Özet

- Ad dosyanın bir özelliği değildir; dizin girdisi bir adı bir düğüme eşler.
- Sabit bağ aynı düğüme ikinci bir girdi ekler; bağlantı sayısı artar ve adlar arasında
  hiyerarşi yoktur.
- Sabit bağ dosya sistemi sınırını geçemez ve dizinlere kurulamaz; `.` ve `..` bu yasağın
  sistem tarafından kurulan istisnalarıdır.
- Sembolik bağ kendi düğümü olan, içeriği bir yol dizesi olan bir dosyadır; boyutu hedef
  dizesinin uzunluğudur.
- Göreli hedefli sembolik bağ, bağın bulunduğu dizine göre çözümlenir; hedef yoksa bağ
  kırıktır ve bu bir hata değil tanımın sonucudur.
- Ağaç içinde göreli, sistem genelindeki sabit konumlarda mutlak hedef tercih edilir.

#### Sonraki Adım

Proje ağacı artık dosyalar, kopyalar ve bağlar içeriyor. Bu ağacın tamamını tek bir dosyaya
paketlemek — başka bir makineye göndermek veya bir zaman noktasını saklamak için — ayrı bir
sorun kümesi doğurur: bağlar nasıl saklanır, dizin yapısı düz bir bayt dizisine nasıl
çevrilir ve sıkıştırma bu işin neresindedir? Sonraki ders arşivleme ile sıkıştırmayı
birbirinden ayırarak başlar.

### Arşivleme ve Sıkıştırma

Source: https://academia.sh/tr/kurslar/linuxa-giris/arsivleme-ve-sikistirma

Arşivlemenin sıkıştırmadan ayrılması, arşiv biçiminin üstveri taşıması, sıkıştırma algoritmalarının oran–maliyet ödünleşimi ve açmadan önce içeriği doğrulama.

Ağacı tek bir dosyaya paketleme sorusu, önceki dersin bıraktığı yerden başlar ve hemen üç
alt soruya ayrılır: dizin yapısı düz bir bayt dizisine nasıl çevrilir, izinler ile zaman
damgaları korunur mu, sembolik bağlar hedeflerinin içeriğiyle mi yoksa yol dizeleriyle mi
saklanır?

Bu ders önce iki işlemi birbirinden ayırır — çoğu araç ikisini birlikte yaptığı için
karıştırılırlar — sonra arşivlerin nasıl doğrulanacağını kurar.

#### İki Ayrı İşlem

**Arşivleme**, birden çok dosyayı üstverileriyle birlikte tek bir bayt dizisine
dönüştürmektir. Boyut küçültmez; hatta biraz büyütür.

**Sıkıştırma**, tek bir bayt dizisini daha kısa bir gösterimle yeniden kodlamaktır. Dosya
sayısını değiştirmez.

Ayrım, Unix geleneğinin "küçük araçlar, tek iş" varsayımının doğrudan bir sonucudur. Her
sıkıştırma algoritması her arşiv biçimiyle birleştirilebilir; iki iş tek programda
birleştirilseydi bu serbestlik kaybolurdu.

Arşiv biçimi, dosya içeriklerinin önüne birer **başlık bloğu** koyar. Başlıkta ad, boyut,
izinler, sahiplik, zaman damgası ve dosya türü bulunur. Bu nedenle arşivden çıkan dosyalar
yalnızca içeriklerini değil üstverilerini de geri kazanır — sıradan bir birleştirme
işleminin yapamayacağı şey budur.

```
$ tar -cf arsiv/veri.tar veri
$ ls -l arsiv
total 56
drwxr-xr-x 2 ogrenci ogrenci  4096 Jul 26 19:04 ham-yedek
-rw-r--r-- 1 ogrenci ogrenci 51200 Jul 26 19:10 veri.tar
```

Seçenekler işlemi belirler: `-c` arşiv oluşturur, `-f` arşiv dosyasının adını verir.
Argüman olarak verilen `veri` dizini özyinelemeli olarak alınır.

Arşiv boyutunun içeriğin toplamından büyük olması beklenen bir sonuçtur. Biçim sabit
uzunlukta bloklar kullanır ve arşivin sonuna dolgu ekler; küçük dosyalarda bu dolgu, veriden
büyük olabilir.

#### Arşivin İçini Görmek

Bir arşivi açmadan önce içeriğini listelemek, uygulanması gereken bir alışkanlıktır:

```
$ tar -tvf arsiv/veri.tar
drwxr-xr-x ogrenci/ogrenci   0 2026-07-26 19:08 veri/
drwxr-xr-x ogrenci/ogrenci   0 2026-07-26 19:03 veri/islenmis/
-rw-r--r-- ogrenci/ogrenci  47 2026-07-26 19:03 veri/islenmis/olcum-01.csv
-rw-r--r-- ogrenci/ogrenci  47 2026-07-26 19:03 veri/islenmis/gunluk-ozet.csv
drwxr-xr-x ogrenci/ogrenci   0 2026-07-26 19:10 veri/ham/
-rw-r--r-- ogrenci/ogrenci  47 2026-07-26 19:02 veri/ham/olcum-01.csv
-rw-r--r-- ogrenci/ogrenci  47 2026-07-26 19:03 veri/ham/olcum-02.csv
-rw-r--r-- ogrenci/ogrenci 42019 2026-07-26 19:10 veri/ham/olcum-04.csv
-rw-r--r-- ogrenci/ogrenci    47 2026-07-26 19:03 veri/ham/olcum-03.csv
lrwxrwxrwx ogrenci/ogrenci     0 2026-07-26 19:08 veri/guncel.csv -> ham/olcum-03.csv
```

`-t` listeler, `-v` ayrıntı ekler. Çıktı, önceki derslerde kurulan her şeyi doğrular.
İzinler ve sahiplik korunmuştur. Zaman damgaları korunmuştur. Son satırdaki sembolik bağ,
hedefinin **kopyası olarak değil, bağ olarak** saklanmıştır: tür karakteri `l`, boyut `0`
ve hedef yol dizesi görünüyor.

Sembolik bağların izlenmesi isteniyorsa `-h` seçeneği verilir; bu durumda arşive bağ değil
hedefin içeriği girer ve arşiv büyür. Ağaç bütün olarak taşınıyorsa varsayılan davranış
doğrudur — bağ da hedefi de arşivdedir ve göreli hedef çözümlenmeye devam eder.

Listeleme alışkanlığının nedeni, arşivlerin **kendi dizin yapılarını taşımasıdır**. İyi
biçimlendirilmiş bir arşiv tek bir üst dizin içerir ve açıldığında yalnızca onu oluşturur.
Böyle olmayan bir arşiv, onlarca dosyayı doğrudan bulunulan dizine boşaltır ve aynı adlı
dosyaların üzerine yazar. Açmadan önce listelemek bu durumu önceden gösterir.

#### Mutlak Yolların Kaldırılması

Arşive mutlak yolla dosya eklenirse araç baştaki eğik çizgiyi kaldırır ve uyarır:

```
$ tar -cf /tmp/mutlak.tar /home/ogrenci/proje/belge
tar: Removing leading `/' from member names
$ tar -tf /tmp/mutlak.tar
home/ogrenci/proje/belge/
```

Bu davranış bir güvenlik önlemidir. Mutlak yollar korunsaydı, arşiv açan bir kullanıcı
sistem dosyalarının üzerine yazan bir arşiv alabilirdi. Yollar göreli tutulduğunda, arşiv
en fazla açıldığı dizinin altını etkiler.

Uyarının pratik sonucu, arşivlerin ağacın **üstünde durup göreli yolla** oluşturulmasıdır:
`tar -cf arsiv/veri.tar veri` komutu `veri/` ile başlayan yollar üretir ve nereye açılırsa
açılsın orada bir `veri` dizini oluşturur.

#### Arşivden Çıkarma

`-x` seçeneği çıkarır, `-C` hedef dizini belirler:

```
$ mkdir -p /tmp/geri
$ tar -xf arsiv/veri.tar -C /tmp/geri
$ find /tmp/geri | sort
/tmp/geri
/tmp/geri/veri
/tmp/geri/veri/guncel.csv
/tmp/geri/veri/ham
/tmp/geri/veri/ham/olcum-01.csv
/tmp/geri/veri/ham/olcum-02.csv
/tmp/geri/veri/ham/olcum-03.csv
/tmp/geri/veri/ham/olcum-04.csv
/tmp/geri/veri/islenmis
/tmp/geri/veri/islenmis/gunluk-ozet.csv
/tmp/geri/veri/islenmis/olcum-01.csv
$ ls -l /tmp/geri/veri/guncel.csv
lrwxrwxrwx 1 ogrenci ogrenci 16 Jul 26 19:08 /tmp/geri/veri/guncel.csv -> ham/olcum-03.csv
```

Ağaç eksiksiz geri gelmiştir ve sembolik bağ bağ olarak yeniden kurulmuştur. Göreli hedefi
sayesinde yeni konumunda da çözümlenir — bağlantılar dersindeki göreli hedef tercihinin
karşılığı burada alınır.

`-C` seçeneği, arşivi bulunulan dizine boşaltma riskini ortadan kaldırır: çıkarma işlemi
her zaman boş veya bu iş için ayrılmış bir dizine yapılır.

#### Sıkıştırma Algoritmaları

Sıkıştırma araçları tek bir dosya üzerinde çalışır ve genellikle özgün dosyanın yerine
sıkıştırılmışını koyar; `-k` seçeneği özgün dosyayı korur.

Üç yaygın algoritmanın aynı veri üzerindeki sonucu:

```
$ gzip -k /tmp/o4.csv
$ bzip2 -k /tmp/o4.csv
$ xz -k /tmp/o4.csv
$ ls -l /tmp/o4.csv*
-rw-r--r-- 1 ogrenci ogrenci 42019 Jul 26 19:10 /tmp/o4.csv
-rw-r--r-- 1 ogrenci ogrenci  5579 Jul 26 19:10 /tmp/o4.csv.bz2
-rw-r--r-- 1 ogrenci ogrenci 10776 Jul 26 19:10 /tmp/o4.csv.gz
-rw-r--r-- 1 ogrenci ogrenci  2444 Jul 26 19:10 /tmp/o4.csv.xz
```

Aynı 42019 baytlık ölçüm dosyası sırasıyla 10776, 5579 ve 2444 bayta inmiştir. Sıralama
rastlantı değildir; algoritmaların tasarım tercihlerinden çıkar.

| Araç | Yaklaşım | Ödünleşim |
|---|---|---|
| `gzip` | Sözlük tabanlı kodlama, küçük pencere | En hızlı, en düşük oran, en yaygın destek |
| `bzip2` | Blok sıralama dönüşümü | Orta hız, orta oran |
| `xz` | Sözlük tabanlı kodlama, çok büyük pencere | En yavaş ve en çok bellek, en yüksek oran |

Ortak ilke şudur: daha yüksek sıkıştırma oranı, daha uzun geçmişte örüntü aramayı
gerektirir; bu da daha çok bellek ve daha çok işlem demektir. Algoritmaların hiçbiri
diğerinden "iyi" değildir; farklı noktalarda durur.

Seçim ölçütü, verinin kaç kez sıkıştırılıp kaç kez açılacağıdır. Bir kez üretilip çok kez
indirilen bir arşivde sıkıştırma maliyeti bir kez ödenir ve yüksek oran kazançlıdır. Sık
üretilen günlük yedeklerde ise sıkıştırma süresi her seferinde ödenir.

Sıkıştırılamayan veri de vardır: zaten sıkıştırılmış görüntü ve ses biçimleri, şifrelenmiş
dosyalar ve rastgele veriler. Bunları sıkıştırmak boyutu küçültmez, bir miktar büyütür —
çıktının en az girdi kadar bilgi taşıması gerektiği için.

#### Arşiv ve Sıkıştırmayı Birleştirmek

Araç, arşivlemeyi ve sıkıştırmayı tek komutta zincirleyebilir:

```
$ tar -czf arsiv/veri.tar.gz veri
$ tar -cJf arsiv/veri.tar.xz veri
$ ls -l arsiv
total 76
drwxr-xr-x 2 ogrenci ogrenci  4096 Jul 26 19:04 ham-yedek
-rw-r--r-- 1 ogrenci ogrenci 51200 Jul 26 19:10 veri.tar
-rw-r--r-- 1 ogrenci ogrenci 11330 Jul 26 19:10 veri.tar.gz
-rw-r--r-- 1 ogrenci ogrenci  4416 Jul 26 19:10 veri.tar.xz
```

`-z` gzip, `-j` bzip2, `-J` xz uygular. Uzantı geleneği sırayı yansıtır: `.tar.gz`, önce
arşivlenip sonra sıkıştırılmış demektir.

Sıranın önemi vardır. Önce arşivleyip sonra sıkıştırmak, dosyalar arasındaki tekrarların da
bulunmasını sağlar; ölçüm dosyaları aynı başlık satırını ve benzer sayı örüntülerini
paylaştığı için bu kazanç gerçektir. Karşılığında tek bir dosyayı okumak için arşivin
başından itibaren açmak gerekir. Her dosyayı ayrı sıkıştırmak ise rastgele erişimi korur ama
dosyalar arası tekrarı kaçırır.

Arşivlerdeki dolgu, sıkıştırmanın oranını da yanıltıcı biçimde yükseltir: 51200 baytlık
arşivin 4416 bayta inmesinin bir bölümü, verinin değil dolgunun sıkışmasıdır. Sıkıştırma
oranı değerlendirilirken ölçüt, arşivin değil özgün verinin boyutudur.

Arşivler hazır olduğuna göre, önceki derste bırakılan dizin kopyası gereksizdir:

```
$ rm -r arsiv/ham-yedek
$ ls -l arsiv
total 72
-rw-r--r-- 1 ogrenci ogrenci 51200 Jul 26 19:10 veri.tar
-rw-r--r-- 1 ogrenci ogrenci 11330 Jul 26 19:10 veri.tar.gz
-rw-r--r-- 1 ogrenci ogrenci  4416 Jul 26 19:10 veri.tar.xz
```

Arşivin dizin kopyasına üstünlüğü, tek dosya olması değil üstveriyi ve bağ yapısını bir
zaman noktasında dondurmasıdır.

#### Taşınabilirlik Notu

Arşiv aracının iki yaygın gerçekleştirimi vardır ve seçenek kümeleri birebir aynı değildir.
Yukarıdaki `-c`, `-t`, `-x`, `-f`, `-v`, `-C` seçenekleri ikisinde de aynı anlamdadır.
Sıkıştırma kısayolları (`-z`, `-j`, `-J`) yaygındır ama standart değildir; taşınabilir
betiklerde sıkıştırma ayrı bir adım olarak boru hattıyla uygulanır.

Eski gerçekleştirimlerde seçenekler tire olmadan da yazılabilir (`tar cf`). Bu biçim
çalışmayı sürdürür; tireli biçim yazılı belgelerde tercih edilir.

#### Özet

- Arşivleme çok dosyayı üstverisiyle birlikte tek bayt dizisine çevirir; sıkıştırma tek bir
  bayt dizisini kısaltır. İki işlem ayrıdır ve bağımsız birleştirilebilir.
- Arşiv başlıkları izin, sahiplik, zaman damgası ve dosya türünü taşır; sembolik bağlar
  hedef dizeleriyle saklanır.
- Arşiv açılmadan önce listelenir; mutlak yollar kaldırılır ve çıkarma `-C` ile ayrılmış bir
  dizine yapılır.
- Sıkıştırma oranı arttıkça bellek ve işlem maliyeti artar; seçim, verinin kaç kez
  sıkıştırılıp kaç kez açılacağına bağlıdır.
- Önce arşivleyip sonra sıkıştırmak dosyalar arası tekrarı yakalar ama rastgele erişimi
  kaybettirir.
- Zaten sıkıştırılmış veya rastgele veri sıkıştırılamaz; çıktı bir miktar büyür.

#### Sonraki Adım

Arşiv tek dosya hâline geldiğine göre başka bir makineye gönderilebilir. Ancak her seferinde
tüm ağacı arşivleyip göndermek, ağacın küçük bir bölümü değiştiğinde savurgandır. Sonraki
ders uzak kopyalama ile eşitleme araçlarını ele alır: bağlantı nasıl kurulur, hangi araç
yalnızca değişeni gönderir ve yol sonundaki eğik çizgi neden sonucu değiştirir?

### Dosya Aktarımı

Source: https://academia.sh/tr/kurslar/linuxa-giris/dosya-aktarimi

Şifreli kabuk üzerinden uzak kopyalama, sunucu kimliğinin doğrulanması, artımlı eşitlemenin yalnızca değişeni göndermesi ve kaynak yolundaki eğik çizginin anlamı.

Önceki ders proje verisini tek bir arşiv dosyasına indirdi. Bu dosya artık başka bir
makineye gönderilebilir — ancak her seferinde tüm ağacı arşivleyip göndermek, ağacın küçük
bir bölümü değiştiğinde gereksiz veri taşır.

Bu ders iki yaklaşımı karşılaştırır: dosyayı olduğu gibi kopyalayan araç ile yalnızca farkı
gönderen araç. Her ikisinden önce, ikisinin de üzerine kurulduğu taşıma katmanı tanıtılır.

Aşağıdaki örneklerde uzak makine `sunucu` adıyla, uzak hesap `yedek` adıyla anılır.

#### Şifreli Kabuk

Uzak makinede komut çalıştırmanın standart yolu **şifreli kabuktur (ssh)**. Sağladığı üç
şey vardır: bağlantı şifrelenir, kullanıcı kimliği doğrulanır ve **sunucunun kimliği**
doğrulanır. Üçüncüsü sık atlanır ama en önemlisidir; şifreleme, karşı tarafın kim olduğu
bilinmiyorsa bir şey ifade etmez.

Bir sunucuya ilk bağlanışta kimliği sorulur:

```
$ ssh yedek@sunucu pwd
The authenticity of host 'sunucu (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:BXO0kZ7GJ+yv/Idqx3h4fOdWRWCgAH6QbY4y0M/YuHk.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'sunucu' (ED25519) to the list of known hosts.
/home/yedek
```

Sunucunun kendine ait bir anahtar çifti vardır ve açık anahtarının özeti **parmak izi**
olarak gösterilir. Onaylandığında bu parmak izi yerel bir dosyaya kaydedilir. Sonraki
bağlantılarda soru sorulmaz:

```
$ ssh yedek@sunucu pwd
/home/yedek
```

Kaydedilen parmak izi bir sonraki bağlantıda uyuşmazsa araç bağlantıyı reddeder ve uyarı
verir. Bu, araya girme girişimini yakalayan mekanizmadır. Uyarı, sunucu yeniden kurulduğunda
da çıkar; her iki durumda da doğru davranış, uyarıyı bastırmak değil parmak izini bağımsız
bir kanaldan doğrulamaktır.

Çıktıdaki `/home/yedek` yolu, komutun uzak makinede ve `yedek` hesabının ev dizininde
çalıştığını gösterir.

Kullanıcı kimliği iki yolla doğrulanır: parola veya anahtar çifti. Anahtar çiftinde özel
anahtar yerel makinede kalır, açık anahtar sunucudaki hesaba yetkilendirilir; parola ağa
hiç çıkmaz. Anahtar yönetimi ve sunucu yapılandırması Linux Ağ Yönetimi ve Sorun Giderme
kursunun konusudur.

#### Uzak Kopyalama

`scp`, yerel kopyalamanın uzak karşılığıdır ve aynı taşıma katmanını kullanır. Uzak yol
`kullanıcı@makine:yol` biçiminde yazılır:

```
$ scp arsiv/veri.tar.xz yedek@sunucu:gelen/
$ ssh yedek@sunucu ls -l gelen
total 8
-rw-r--r-- 1 yedek yedek 4416 Jul 26 19:16 veri.tar.xz
```

İki nokta üst üste ayıracı belirleyicidir: `yedek@sunucu:gelen/` uzak bir yolu,
`yedek@sunucu` ise `yedek@sunucu` adında yerel bir dosyayı belirtir. Ayıraç unutulduğunda
komut hata vermez, yerel bir dosya oluşturur.

Uzak yollarda göreli yol, oturum açan kullanıcının ev dizinine göredir. `gelen/` yolu
`/home/yedek/gelen/` anlamına gelir.

`scp` dosyayı bütün olarak gönderir; hedefte aynı içerik varsa bile yeniden aktarır. Dizin
göndermek için `-r` gerekir, tıpkı yerel kopyalamada olduğu gibi.

#### Aktarımın Doğrulanması

Aktarımın eksiksiz olduğu, içeriğin özetiyle sınanır:

```
$ sha256sum arsiv/veri.tar.xz
6608712cb484f9629dcdf1cbaa3bced3cb87ff00b24d6d32646775ccff3b5443  arsiv/veri.tar.xz
$ ssh yedek@sunucu sha256sum gelen/veri.tar.xz
6608712cb484f9629dcdf1cbaa3bced3cb87ff00b24d6d32646775ccff3b5443  gelen/veri.tar.xz
```

İki özet aynıysa iki dosyanın içeriği aynıdır. Boyut karşılaştırması bu güvenceyi vermez:
aynı boyutlu iki farklı içerik olabilir, ama aynı özetli iki farklı içerik pratikte
bulunamaz.

Özet doğrulaması yalnızca aktarım hatalarına karşı değildir; arşivin kaynağında
değiştirilip değiştirilmediğini de sınar. Bu nedenle yazılım dağıtımlarında paketlerin
yanında özet dosyaları yayımlanır — depo yapılandırması dersinde aynı ilke imza zinciriyle
birlikte ele alınacaktır.

#### Eşitleme

`rsync` kopyalamaz, **eşitler**: kaynakla hedefi karşılaştırır ve yalnızca farkı gönderir.
Karşılaştırma varsayılan olarak boyut ve değişiklik zamanı üzerinden yapılır.

Çalıştırmadan önce ne yapacağını göstermesi istenebilir:

```
$ rsync -avn veri/ yedek@sunucu:gelen/veri/
sending incremental file list
created directory gelen/veri
./
guncel.csv -> ham/olcum-03.csv
ham/
ham/olcum-01.csv
ham/olcum-02.csv
ham/olcum-03.csv
ham/olcum-04.csv
islenmis/
islenmis/gunluk-ozet.csv
islenmis/olcum-01.csv

sent 351 bytes  received 81 bytes  864.00 bytes/sec
total size is 42,270  speedup is 97.85 (DRY RUN)
```

`-n` **kuru çalışma** yapar: hiçbir şey aktarılmaz, yalnızca yapılacaklar listelenir. Son
satırdaki `(DRY RUN)` bunu doğrular. `-a` üstveriyi koruyan bir seçenek kümesidir — izinler,
zaman damgaları ve sembolik bağlar korunur; listede `guncel.csv -> ham/olcum-03.csv`
satırının bağ olarak görünmesi bunun sonucudur. `-v` işlenen dosyaları yazdırır.

Kuru çalışma onaylandıktan sonra aynı komut `-n` olmadan çalıştırılır. Asıl fark, ikinci
çalıştırmada görünür:

```
$ rsync -av veri/ yedek@sunucu:gelen/veri/
sending incremental file list
ham/olcum-01.csv

sent 430 bytes  received 43 bytes  946.00 bytes/sec
total size is 42,284  speedup is 89.40
```

Arada yalnızca bir ölçüm dosyası değiştirilmişti. Listede yalnızca o dosya var; gönderilen
veri 430 bayt, ağacın toplam büyüklüğü 42 kilobayttan fazla. Aynı işi `scp -r` ile yapmak
her seferinde ağacın tamamını göndermek olurdu.

Değişmeyen dosyaların hiç açılmaması, eşitlemeyi düzenli yedeklerin standart aracı yapar:
maliyet ağacın büyüklüğüyle değil, değişimin büyüklüğüyle orantılıdır.

#### Eğik Çizgi Kaynağın Anlamını Değiştirir

Eşitleme aracının en sık yanlış kullanılan ayrıntısı, **kaynak yolunun sonundaki eğik
çizgidir**.

Yukarıdaki komutlarda kaynak `veri/` biçiminde yazılmıştı: sondaki eğik çizgi "bu dizinin
**içindekiler**" anlamına gelir ve içerik doğrudan hedefe yerleşir. Eğik çizgi
kaldırıldığında anlam değişir:

```
$ rsync -avn veri yedek@sunucu:gelen/deneme/
sending incremental file list
created directory gelen/deneme
veri/
veri/guncel.csv -> ham/olcum-03.csv
veri/ham/
veri/ham/olcum-01.csv
veri/ham/olcum-02.csv
veri/ham/olcum-03.csv
veri/ham/olcum-04.csv
veri/islenmis/
veri/islenmis/gunluk-ozet.csv
veri/islenmis/olcum-01.csv

sent 370 bytes  received 84 bytes  908.00 bytes/sec
total size is 42,284  speedup is 93.14 (DRY RUN)
```

Yollar artık `veri/` önekiyle listeleniyor: dizinin kendisi hedefin içine yerleşiyor ve
sonuç `gelen/deneme/veri/...` oluyor. Aynı komutun iki biçimi, bir düzey farkla iki ayrı
ağaç üretir.

Hedef yolundaki eğik çizginin böyle bir etkisi yoktur. Kural yalnızca kaynak için geçerlidir
ve kuru çalışma bu farkı her seferinde görünür kılar.

#### Hedefteki Fazlalıklar

Eşitleme varsayılan olarak hedefteki fazladan dosyaları silmez. Kaynakta olmayan bir dosya
hedefte duruyorsa orada kalır:

```
$ rsync -av veri/ yedek@sunucu:gelen/veri/
sending incremental file list
./

sent 329 bytes  received 21 bytes  700.00 bytes/sec
total size is 42,284  speedup is 120.81
$ ssh yedek@sunucu ls gelen/veri
eski-olcum.csv
guncel.csv
ham
islenmis
```

Hedefi kaynağın birebir yansıması yapmak için `--delete` gerekir:

```
$ rsync -avn --delete veri/ yedek@sunucu:gelen/veri/
sending incremental file list
deleting eski-olcum.csv

sent 326 bytes  received 39 bytes  730.00 bytes/sec
total size is 42,284  speedup is 115.85 (DRY RUN)
```

Bu seçenek yıkıcıdır ve silme dersindeki uyarı burada birebir geçerlidir: kaynak yolu
yanlış yazılırsa veya boş bir dizini gösterirse, hedefteki her şey silinir. `--delete`
kullanılan her komut önce `-n` ile çalıştırılmalıdır; kuru çalışma listesindeki `deleting`
satırları, silinecek dosyaların tam listesidir.

#### Araç Seçimi

| Ölçüt | `scp` | `rsync` |
|---|---|---|
| Gönderilen veri | Dosyanın tamamı | Yalnızca fark |
| Yinelenen çalıştırma | Aynı maliyet | Değişim kadar maliyet |
| Üstveri koruma | Sınırlı | `-a` ile tam |
| Kuru çalışma | Yok | `-n` ile var |
| Hedefte silme | Yok | `--delete` ile var |
| Karşı tarafta gereksinim | Yok | Aracın kurulu olması |

Tek seferlik ve tek dosyalık aktarımlarda kopyalama yeterlidir; yinelenen ağaç
aktarımlarında eşitleme tercih edilir. Etkileşimli gezinme ve seçerek indirme gerekiyorsa
`sftp` aracı aynı taşıma katmanı üzerinde dosya sistemi benzeri bir oturum sağlar.

#### Özet

- Şifreli kabuk hem kullanıcıyı hem sunucuyu doğrular; sunucunun parmak izi ilk bağlantıda
  onaylanır ve sonraki bağlantılarda karşılaştırılır.
- Uzak yollar `kullanıcı@makine:yol` biçiminde yazılır; iki nokta üst üste unutulduğunda
  komut sessizce yerel bir dosya oluşturur.
- Aktarım, içerik özetlerinin karşılaştırılmasıyla doğrulanır; boyut eşitliği güvence
  vermez.
- Eşitleme yalnızca değişen dosyaları gönderir; maliyet ağacın değil değişimin
  büyüklüğüyle orantılıdır.
- Kaynak yolundaki sondaki eğik çizgi "dizinin içindekiler", çizgisiz biçim "dizinin
  kendisi" anlamına gelir.
- `--delete` hedefi kaynağın birebir yansıması yapar ve yıkıcıdır; kuru çalışmayla önce
  denetlenmelidir.

#### Sonraki Adım

Uzak makinedeki dosyalar `yedek` hesabına ait çıktı; yerel dosyalar ise başka bir hesaba.
Bu ayrımın nasıl kurulduğu — kullanıcı kimliğinin sistemde ne olarak saklandığı, grupların
ne işe yaradığı ve bir dosyanın kime ait olduğunun ne anlama geldiği — henüz açıklanmadı.
Sonraki konu hesap modelini kurar ve buradan izin bitlerine geçer.

## Kullanıcılar ve İzinler

Hesap modeli, kimlik dosyaları, izin bitlerinin sekizlik gösterimi, sahiplik yönetimi, yetki yükseltme ve özel izin bitleri.

### Kullanıcılar ve Gruplar

Source: https://academia.sh/tr/kurslar/linuxa-giris/kullanicilar-ve-gruplar

Kimliğin çekirdek düzeyinde sayı olarak tutulması, hesap ve grup dosyalarının alan yapısı, birincil ile ek grup ayrımı ve ad çözümlemesi.

Önceki derste uzak makinedeki dosyalar `yedek` hesabına, yerel dosyalar başka bir hesaba ait
çıktı. Listeleme çıktılarında sahip ve grup sütunları en baştan beri görünüyordu ama ne
oldukları açıklanmadı.

Bu ders o boşluğu kapatır. Kimliğin sistemde ne olarak saklandığı, sonraki dersteki izin
denetiminin girdisidir: çekirdek "bu kullanıcı bu dosyayı okuyabilir mi" sorusunu yanıtlarken
tam olarak bu değerleri karşılaştırır.

#### Kimlik Bir Sayıdır

Çekirdek kullanıcı adı bilmez. Her sürecin ilişkilendirildiği şey iki tam sayıdır:
**kullanıcı kimliği (UID)** ve **grup kimliği (GID)**. Adlar yalnızca insanlar içindir ve
kullanıcı alanındaki programlarca çözülür.

```
$ id
uid=1001(ogrenci) gid=1001(ogrenci) groups=1001(ogrenci),2001(proje)
```

Çıktı üç bilgi verir: kullanıcı kimliği, birincil grup kimliği ve üyesi olunan tüm gruplar.
Parantez içindeki adlar sayıların çözülmüş karşılıklarıdır; asıl değer sayıdır.

Alanlar ayrı ayrı da istenebilir:

```
$ id -u
1001
$ id -g
1001
$ id -un
ogrenci
```

`-n` eki, sayı yerine adı verir. `whoami` komutu `id -un` ile aynı sonucu üretir.

Ayrımın pratik sonucu şudur: bir dosyanın sahibi bir ad değil bir sayıdır. Kullanıcı
silinip aynı numarayla yeni bir hesap açılırsa, eski dosyalar yeni hesaba ait görünür. Aynı
biçimde, arşivden çıkarılan dosyaların sahipliği hedef sistemde farklı bir kişiye denk
gelebilir — arşiv dosyalarında saklanan da sayıdır.

**Kök kullanıcı (root)** UID değeri sıfır olan hesaptır. Ayrıcalığı adından değil bu
sayıdan gelir; çekirdek birçok denetimi UID sıfır için atlar.

#### Hesap Dosyası

Hesap kayıtları bir metin dosyasında tutulur. Her satır bir hesaptır ve alanlar iki nokta
üst üste ile ayrılır:

```
$ grep -E '^(root|ogrenci|yedek):' /etc/passwd
root:x:0:0:root:/root:/bin/bash
ogrenci:x:1001:1001::/home/ogrenci:/bin/bash
yedek:x:1002:1002::/home/yedek:/bin/bash
```

Yedi alan sırayla şunlardır:

| Sıra | Alan | Örnekteki değer |
|---|---|---|
| 1 | Kullanıcı adı | `ogrenci` |
| 2 | Parola yeri | `x` |
| 3 | Kullanıcı kimliği | `1001` |
| 4 | Birincil grup kimliği | `1001` |
| 5 | Açıklama alanı | boş |
| 6 | Ev dizini | `/home/ogrenci` |
| 7 | Oturum açma kabuğu | `/bin/bash` |

Bu dosyanın biçimi, yardım kaynakları dersinde kılavuzun beşinci bölümünden okunmuştu;
bölüm 5'in ne işe yaradığının somut örneği budur.

İkinci alandaki `x` bir parola değildir. Parola karmaları, yalnızca kök kullanıcının
okuyabildiği ayrı bir dosyada tutulur:

```
$ ls -l /etc/passwd /etc/shadow
-rw-r--r-- 1 root root   1236 Jul 26 19:14 /etc/passwd
-rw-r----- 1 root shadow  668 Jul 26 19:14 /etc/shadow
$ cat /etc/shadow
cat: /etc/shadow: Permission denied
```

Ayrımın nedeni izin sütunlarında görünür: hesap dosyası herkes tarafından okunabilir
(`rw-r--r--`), çünkü kullanıcı adı ve kimlik eşlemesine her program erişmek zorundadır.
Parola karmaları aynı erişilebilirlikte olsaydı, herkes karmaları alıp çevrimdışı deneme
yapabilirdi. Karmalar bu yüzden ayrılmıştır ve yalnızca sahibi ile `shadow` grubu tarafından
okunabilir.

Sistem hesapları ile insan hesapları kimlik aralıklarıyla ayrılır. Düşük numaralar
servisler için ayrılmıştır; insan hesapları belirli bir eşiğin üzerinden başlar. Eşiğin
değeri sistem yapılandırmasına bağlıdır, ama ayrımın kendisi geneldir ve yeni hesap açan
araçlar numarayı bu aralıktan seçer.

Yedinci alandaki kabuk, oturum açıldığında çalıştırılacak programdır. Oturum açması
istenmeyen servis hesaplarında buraya, çalıştırıldığında hemen sonlanan bir program yazılır;
bu, hesabı devre dışı bırakmanın standart yoludur.

#### Hesabın Yaşam Döngüsü

Hesap dosyaları elle düzenlenmez; hesap yönetimi komutları bu dosyaları tutarlı biçimde
günceller. Yeni bir hesap açan komut tek bir dosyaya değil üçüne birden yazar: hesap
dosyasına bir satır, gölge dosyasına bir parola kaydı, grup dosyasına birincil grup. Ayrıca
ev dizinini oluşturur ve içine iskelet dizininden başlangıç yapılandırma dosyalarını
kopyalar.

Ek grup üyeliği sonradan verilebilir. Burada sık karşılaşılan bir yanılgı vardır: üyelik
eklendiği anda çalışan oturuma yansımaz. Süreçlerin grup listesi oturum açılırken belirlenir
ve süreç boyunca sabit kalır; yeni üyelik ancak yeni bir oturumda geçerli olur.

Hesabın kapatılması ile silinmesi ayrı işlerdir. **Kapatma**, parolayı geçersiz kılar veya
oturum kabuğunu sonlandıran bir programla değiştirir; kimlik ve dosya sahipliği yerinde
kalır. **Silme**, kaydı dosyalardan çıkarır — ama kullanıcının sistemde bıraktığı dosyaları
temizlemez.

Sonuç, kimliğin bir sayı olmasının doğrudan görünür hâlidir:

```
$ ls -l /veri/rapor.txt
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:54 /veri/rapor.txt
$ sudo userdel ogrenci
$ ls -l /veri/rapor.txt
-rw-r--r-- 1 1001 1001 0 Jul 26 19:54 /veri/rapor.txt
```

Sahip sütununda ad yerine sayı görünür: dosyanın sahipliği değişmemiştir, yalnızca sayıyı
ada çevirecek kayıt kalmamıştır. Bu tür dosyalar, aynı numara başka bir hesaba verildiğinde
sessizce onun olur; hesap silinirken dosyalarının da devredilmesi ya da temizlenmesi
gereken şey budur.

#### Grup Dosyası

Gruplar ayrı bir dosyada, dört alanla tutulur:

```
$ grep -E '^(root|ogrenci|yedek|proje):' /etc/group
root:x:0:
ogrenci:x:1001:
proje:x:2001:ogrenci
yedek:x:1002:
```

Alanlar sırayla grup adı, parola yeri, grup kimliği ve **ek üyelerin** listesidir.

Son alan dikkat ister. `ogrenci` grubunun üye listesi boştur, ama `ogrenci` kullanıcısı bu
grubun üyesidir. Çelişki değildir: üyelik iki ayrı yerden gelir.

**Birincil grup**, hesap dosyasının dördüncü alanındadır. Kullanıcının oluşturduğu yeni
dosyalar varsayılan olarak bu grubu alır.

**Ek gruplar**, grup dosyasının üye listelerinden gelir. `proje:x:2001:ogrenci` satırı
`ogrenci` kullanıcısını `proje` grubuna ek üye yapar.

Toplam üyelik iki kaynağın birleşimidir:

```
$ groups
ogrenci proje
```

Her kullanıcıya kendi adıyla bir birincil grup açmak yaygın bir yapılandırmadır. Nedeni izin
bitleri dersinde görülecektir: birincil grup paylaşılan bir grup olsaydı, kullanıcının
oluşturduğu her dosya varsayılan olarak o gruba açık olurdu.

Bu kursun proje ağacı için ayrı bir `proje` grubu tanımlanmıştır. Grup, sahiplik ve özel
izin bitleri derslerinde ağacın paylaşıma açılmasında kullanılacaktır.

#### Ad Çözümleme

Kimlik bilgisi her zaman yerel dosyalardan gelmez. Kuruluş ölçeğinde hesaplar ağ üzerindeki
bir dizin hizmetinde tutulabilir. Bu nedenle programlar dosyaları doğrudan okumak yerine bir
çözümleme katmanı çağırır.

```
$ getent passwd ogrenci
ogrenci:x:1001:1001::/home/ogrenci:/bin/bash
$ getent group proje
proje:x:2001:ogrenci
```

`getent` komutu, sistemin yapılandırılmış tüm kaynaklarına sorar ve yanıtı standart biçimde
verir. Kayıt yerel dosyada değil ağdaki bir kaynakta olsa da çıktı aynı biçimdedir; komutu
çağıran programın kaynağın nerede olduğunu bilmesi gerekmez.

Uygulamada bunun anlamı şudur: bir hesabın var olup olmadığı `grep` ile dosyada aranarak
değil, `getent` ile sorularak sınanır. Dosyada bulunmaması hesabın olmadığını göstermez.

#### Hesap Yönetimi Komutları

Hesap ve grup oluşturma, değiştirme ve silme komutları kök yetkisi gerektirir ve kılavuzun
sekizinci bölümünde belgelenir. Bu kursta hesap açılmayacaktır; ilgili araç ailesi Sistem
Yönetimi kursunun konusudur.

Kök yetkisi gerektirmeyen tek yaygın işlem, kullanıcının kendi parolasını değiştirmesidir.
Bu işlemin nasıl mümkün olduğu ilginç bir sorudur: parola karmalarını tutan dosya sıradan
bir kullanıcı tarafından okunamaz bile, yazılması nasıl sağlanır?

```
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 72056 May 30  2024 /usr/bin/passwd
```

İzin dizesinde alışılmadık bir karakter var: sahip izinlerinin üçüncü konumunda `x` yerine
`s`. Bu, özel izin bitleri dersinin konusudur ve bu konunun sonunda yanıtlanacaktır.

#### Özet

- Çekirdek kimliği sayı olarak tutar; adlar kullanıcı alanında çözülür ve dosya sahipliği
  sayıya bağlıdır.
- Kök kullanıcının ayrıcalığı adından değil, kullanıcı kimliğinin sıfır olmasından gelir.
- Hesap dosyası yedi alan taşır: ad, parola yeri, kullanıcı kimliği, birincil grup kimliği,
  açıklama, ev dizini ve oturum kabuğu.
- Parola karmaları, çevrimdışı deneme saldırılarını engellemek için yalnızca ayrıcalıklı
  okunabilen ayrı bir dosyadadır.
- Üyelik iki kaynaktan gelir: hesap dosyasındaki birincil grup ve grup dosyasındaki ek üye
  listeleri.
- Ad çözümleme yerel dosyalarla sınırlı değildir; sorgular çözümleme katmanı üzerinden
  yapılır.

#### Sonraki Adım

Kimlik tanımlandığına göre, bu kimliğin bir dosyada ne yapabileceği sorulabilir. Sonraki ders
listeleme çıktısının ilk sütunundaki dokuz karakteri çözer: üç erişim türü, üç kullanıcı
sınıfı, sekizlik gösterim ve dizinlerde aynı bitlerin neden bambaşka anlamlar taşıdığı.

### İzin Bitleri

Source: https://academia.sh/tr/kurslar/linuxa-giris/izin-bitleri

Dokuz izin bitinin üç sınıf ve üç erişim türüne bölünmesi, sekizlik gösterim, sınıf seçiminin dışlayıcılığı, dizinlerde bitlerin farklı anlamı ve varsayılan izinleri belirleyen maske.

Önceki ders kimliği tanımladı. Şimdi bu kimliğin bir dosyada ne yapabileceği sorulabilir.
Yanıt, listeleme çıktısının ilk sütununda en baştan beri duruyordu:

```
$ ls -l betik/ozet.sh
-rwxr-xr-x 1 ogrenci ogrenci 139 Jul 26 18:49 betik/ozet.sh
$ ls -l veri/ham/olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 61 Jul 26 19:17 veri/ham/olcum-01.csv
```

İlk karakter dosya türüdür ve izinle ilgisizdir. Kalan dokuz karakter, çekirdeğin her erişim
isteğinde danıştığı tablodur.

#### Üç Sınıf, Üç Erişim

Dokuz karakter üçerli üç gruba bölünür. Gruplar **kullanıcı sınıflarına** karşılık gelir:

- İlk üç: dosyanın **sahibi**
- Orta üç: dosyanın **grubu**
- Son üç: **diğerleri**

Her grup içinde üç erişim türü aynı sırada durur: okuma (`r`), yazma (`w`), çalıştırma
(`x`). İzin verilmemişse yerinde tire bulunur.

Buna göre `-rwxr-xr-x` şu anlama gelir: sahip okuyabilir, yazabilir, çalıştırabilir; grup
üyeleri okuyabilir ve çalıştırabilir, yazamaz; diğerleri de aynı.

#### Sınıf Seçimi Dışlayıcıdır

En sık yapılan yanlış varsayım, izinlerin birikimli olduğudur. Değildir. Çekirdek sırayla
tek bir sınıf seçer ve **yalnızca onu** uygular:

1. İsteği yapan sürecin kullanıcı kimliği dosyanın sahibiyse: sahip bitleri uygulanır.
2. Değilse, kullanıcının gruplarından biri dosyanın grubuysa: grup bitleri uygulanır.
3. Hiçbiri değilse: diğer bitleri uygulanır.

Karar verildikten sonra diğer sınıflara bakılmaz. Bunun şaşırtıcı sonucu, sahibin kendi
dosyasına diğerlerinden daha az erişebilmesidir:

```
$ chmod 044 /tmp/sinif.csv
$ ls -l /tmp/sinif.csv
----r--r-- 1 ogrenci ogrenci 47 Jul 26 19:20 /tmp/sinif.csv
$ id -un
ogrenci
$ cat /tmp/sinif.csv
cat: /tmp/sinif.csv: Permission denied
```

Dosyanın sahibi `ogrenci`'dir ve okuma girişimi reddedilmiştir. Grup ve diğer sınıflarda
okuma izni vardır, ama sahip sınıfı seçildiği için onlara bakılmamıştır.

Sahibin bir üstünlüğü yine de vardır: izinleri değiştirme hakkı bitlerde tutulmaz,
sahiplikten gelir. Sahip kendini kilitleyebilir ama kilidi her zaman açabilir.

```
$ chmod 644 /tmp/sinif.csv
$ cat /tmp/sinif.csv
zaman,sicaklik,nem
08:00,19.8,61
12:00,23.1,52
```

#### Sekizlik Gösterim

Dokuz bit, üçerli gruplar hâlinde okunduğunda üç sekizlik basamak verir. Bilgisayarlar Nasıl
Çalışır kursundaki sekizlik taban tam olarak bu iş için uygundur: her basamak tam olarak üç
biti kodlar.

Ağırlıklar erişim türlerine göre sabittir:

| Erişim | Harf | Değer |
|---|---|---|
| Okuma | `r` | 4 |
| Yazma | `w` | 2 |
| Çalıştırma | `x` | 1 |

Bir sınıfın basamağı, o sınıfta açık olan bitlerin toplamıdır:

| Sekizlik | Bitler | Anlamı |
|---|---|---|
| 7 | `rwx` | $4+2+1$ |
| 6 | `rw-` | $4+2$ |
| 5 | `r-x` | $4+1$ |
| 4 | `r--` | $4$ |
| 0 | `---` | $0$ |

Böylece `-rwxr-xr-x` dizesi `755`, `-rw-r--r--` dizesi `644` ve yukarıdaki `----r--r--`
dizesi `044` olur.

Sekizlik gösterimin üstünlüğü kesinliktir: `chmod 644` komutu dokuz biti de belirler, önceki
durumu ne olursa olsun. Harfli gösterim ise seçici değişiklik yapar.

#### Simgesel Gösterim

`chmod` komutunun harfli biçimi üç parçadan oluşur: hangi sınıf (`u` sahip, `g` grup, `o`
diğerleri, `a` hepsi), hangi işlem (`+` ekle, `-` çıkar, `=` tam olarak ayarla) ve hangi
bitler.

```
$ chmod 644 /tmp/s.txt
$ ls -l /tmp/s.txt
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/s.txt
$ chmod u+x /tmp/s.txt
$ ls -l /tmp/s.txt
-rwxr--r-- 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/s.txt
$ chmod go-r /tmp/s.txt
$ ls -l /tmp/s.txt
-rwx------ 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/s.txt
$ chmod a=r /tmp/s.txt
$ ls -l /tmp/s.txt
-r--r--r-- 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/s.txt
```

`+` ve `-` yalnızca adı geçen bitlere dokunur; diğerleri korunur. `=` ise o sınıfın tüm
bitlerini verilen değere ayarlar, yani listelenmemiş bitleri kapatır.

Seçim ölçütü nettir: bilinen bir duruma getirmek için sekizlik, var olan duruma ekleme veya
çıkarma yapmak için simgesel biçim kullanılır. Komut yolu dersindeki `chmod +x` kullanımı
ikinci türdendi — dosyanın okuma izinleri korunarak yalnızca çalıştırma eklenmişti.

#### Dizinlerde Bitlerin Anlamı Değişir

Aynı üç harf dizinlerde bambaşka şeyler ifade eder. Bu, izin modelinin en çok yanlış
anlaşılan yanıdır.

**Okuma (`r`)** dizindeki **adların listelenmesine** izin verir.

**Yazma (`w`)** dizine **girdi eklemeye ve girdi silmeye** izin verir.

**Çalıştırma (`x`)** dizinden **geçmeye**, yani içindeki bir ada erişmeye izin verir. Dizin
hiyerarşisi dersinde yolun bileşen bileşen çözümlendiği söylenmişti; her bileşende aranan
izin budur.

İki bit birbirinden bağımsızdır ve ayrı ayrı sınanabilir. Yalnızca geçiş izni olan bir
dizin, içeriği listelenemez ama adı bilinen dosyaya erişilebilir:

```
$ chmod 100 /tmp/dz
$ ls -ld /tmp/dz
d--x------ 3 ogrenci ogrenci 4096 Jul 26 19:20 /tmp/dz
$ ls /tmp/dz
ls: cannot open directory '/tmp/dz': Permission denied
$ cat /tmp/dz/veri.txt
icerik
```

Listeleme reddedilmiş, ama adı doğrudan verilen dosya okunabilmiştir. Bu yapılandırma
pratikte kullanılır: içeriği gizli tutulan ama belirli dosyalarına erişim verilen dizinler
böyle ayarlanır.

Tersi durum daha çarpıcıdır — okuma var, geçiş yok:

```
$ chmod 400 /tmp/dz
$ ls -ld /tmp/dz
dr-------- 3 ogrenci ogrenci 4096 Jul 26 19:20 /tmp/dz
$ ls /tmp/dz
alt  veri.txt
$ ls -l /tmp/dz
ls: cannot access '/tmp/dz/alt': Permission denied
ls: cannot access '/tmp/dz/veri.txt': Permission denied
total 0
d????????? ? ? ? ?            ? alt
-????????? ? ? ? ?            ? veri.txt
```

Adlar okunabilmiştir çünkü adlar dizinin **içeriğidir**. Ancak her adın üstverisini almak
için dizinden geçmek gerekir ve geçiş izni yoktur; bu yüzden tüm sütunlar soru işaretiyle
gösterilmiştir. Çıktı, adların dizinde, üstverinin düğümde durduğu ayrımını doğrudan
görünür kılar.

Yazma bitinin sonucu da beklenmediktir: bir dizinde yazma izni olan kullanıcı, **içindeki
dosyaları silebilir** — dosyanın kendisinde hiçbir izni olmasa bile. Silmek dosyayı değil
dizin girdisini değiştirdiği için, aranan izin dizinin iznidir. Bu boşluğun nasıl
kapatıldığı özel izin bitleri dersinin konusudur.

#### Varsayılan İzinler

Yeni oluşturulan dosyaların izinleri komutla verilmez; **maskeden (umask)** çıkar. Maske,
kapatılacak bitleri gösterir: istenen izinlerden maskedeki bitler çıkarılır.

```
$ umask
0022
$ touch /tmp/u1.txt
$ mkdir -p /tmp/u1dir
$ ls -l /tmp/u1.txt
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/u1.txt
$ ls -ld /tmp/u1dir
drwxr-xr-x 2 ogrenci ogrenci 4096 Jul 26 19:20 /tmp/u1dir
```

Hesap şöyledir: dosyalar için başlangıç değeri `666`, dizinler için `777`'dir. Maske `022`
çıkarıldığında dosyalarda `644`, dizinlerde `755` kalır.

Dosyaların `777` yerine `666` ile başlaması bilinçlidir: çalıştırma izni istem dışı
verilmemelidir, çünkü bir veri dosyasının çalıştırılabilir olması hiçbir zaman gerekli
değildir. Dizinlerde ise geçiş izni olmadan dizin kullanılamaz.

Maske değiştirilebilir:

```
$ umask 077
$ touch /tmp/u2.txt
$ mkdir -p /tmp/u2dir
$ ls -l /tmp/u2.txt
-rw------- 1 ogrenci ogrenci 0 Jul 26 19:20 /tmp/u2.txt
$ ls -ld /tmp/u2dir
drwx------ 2 ogrenci ogrenci 4096 Jul 26 19:20 /tmp/u2dir
```

`077` maskesi grup ve diğer sınıfların tüm bitlerini kapatır; yeni dosyalar yalnızca sahibe
açık olur. Çok kullanıcılı sistemlerde bu, varsayılan olarak tercih edilen ayardır.

Maske süreç özelliğidir ve çocuk süreçlere miras kalır; kalıcı olması için oturum açılışında
okunan yapılandırma dosyasına yazılır — komut yolu dersindeki `PATH` ayarıyla aynı yere.

#### Özet

- Dokuz izin biti üç sınıfa (sahip, grup, diğerleri) ve üç erişim türüne (okuma, yazma,
  çalıştırma) bölünür.
- Sınıf seçimi dışlayıcıdır: uyan ilk sınıf uygulanır ve diğerlerine bakılmaz; sahip kendi
  dosyasına diğerlerinden az erişebilir.
- Sekizlik gösterimde okuma 4, yazma 2, çalıştırma 1 değerindedir; `chmod` sekizlikle tam
  durum, simgesel biçimle seçici değişiklik yapar.
- Dizinlerde okuma adları listelemeye, yazma girdi eklemeye ve silmeye, çalıştırma dizinden
  geçmeye izin verir.
- Dizinde yazma izni olan kullanıcı, içindeki dosyalarda hiçbir izni olmasa da onları
  silebilir.
- Yeni dosyaların izinleri maskeyle belirlenir: dosyalarda `666`, dizinlerde `777`
  başlangıç değerinden maske bitleri çıkarılır.

#### Sonraki Adım

İzinler bir dosyanın sahibine ve grubuna göre uygulanıyorsa, sahiplik ve grubun kendisi
nasıl değiştirilir? Sonraki ders sahiplik değiştirme komutlarını, kimin neyi
değiştirebileceğini ve bir ağacın tamamının sahipliğini değiştirirken sembolik bağların neden
sorun çıkardığını ele alır.

### Sahiplik Değiştirme

Source: https://academia.sh/tr/kurslar/linuxa-giris/sahiplik-degistirme

Sahip ve grup değiştirme komutları, sahip devrinin neden ayrıcalık gerektirdiği, özyinelemeli değişiklikte sembolik bağ davranışı ve ağacın gruba açılması.

İzinler dosyanın sahibine ve grubuna göre uygulanıyorsa, sahiplik ve grubun kendisi nasıl
belirlenir? Önceki dersin tablosu eksikti: dokuz bit kimin ne yapabileceğini söylüyordu ama
"kim" sorusunun yanıtı dosyanın üstverisinde duran iki sayıydı ve bu sayıların nasıl
değiştiği açıklanmadı.

Bu ders o iki alanı değiştiren komutları ve —daha önemlisi— bunları kimin
değiştirebileceğini ele alır. Yetki kısıtı keyfi değildir; kaldırılması durumunda izin
modelinin kendisi anlamsızlaşır.

#### Sahip Devri Ayrıcalık İster

Sıradan bir kullanıcı, sahibi olduğu dosyayı bile başkasına devredemez:

```
$ ls -l veri/ham/olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 61 Jul 26 19:17 veri/ham/olcum-01.csv
$ chown yedek veri/ham/olcum-01.csv
chown: changing ownership of 'veri/ham/olcum-01.csv': Operation not permitted
```

Kısıtın iki gerekçesi vardır.

**Disk kotası.** Kullanılan alan dosya sahibine yazılır. Sahip devri serbest olsaydı,
kotasını dolduran bir kullanıcı dosyalarını başkasının üzerine geçirerek kotayı sıfırlardı.
Devir bu nedenle yalnızca kök kullanıcıya bırakılmıştır.

**Yetki devri.** Özel izin bitleri dersinde görüleceği gibi, bir dosya çalıştırıldığında
sahibinin yetkileriyle çalışacak biçimde işaretlenebilir. Sahip devri serbest olsaydı, böyle
bir dosya hazırlayıp sahipliğini ayrıcalıklı bir hesaba geçirmek yetki yükseltmenin en kısa
yolu olurdu.

Kısıtın yönü tek taraflıdır: dosyayı kendine almak da, başkasına vermek de yasaktır. Kural
"sahip değişmez" biçiminde okunabilir; değiştirebilen tek hesap kök kullanıcıdır.

#### Grup Değişikliği

Grup için kural farklıdır. Dosyanın sahibi, dosyanın grubunu **üyesi olduğu** herhangi bir
gruba çevirebilir:

```
$ chgrp proje veri/ham/olcum-01.csv
$ ls -l veri/ham/olcum-01.csv
-rw-r--r-- 1 ogrenci proje 61 Jul 26 19:17 veri/ham/olcum-01.csv
```

Üyesi olunmayan bir gruba çevirmek yasaktır:

```
$ chgrp yedek veri/ham/olcum-01.csv
chgrp: changing group of 'veri/ham/olcum-01.csv': Operation not permitted
```

Bu da tutarlı bir kısıttır: kullanıcı yalnızca zaten sahip olduğu bir yetkiyi devredebilir.
Üyesi olmadığı bir gruba dosya vermek, o grubun üyelerine kendi verisi üzerinde hak
tanımak — ya da onların ad alanını kirletmek — anlamına gelirdi.

Önceki derste `groups` çıktısında görülen üyelikler burada doğrudan kullanılır: bir
kullanıcının dosyalarını hangi gruplara açabileceğini o liste belirler.

#### Tek Komutla İki Alan

`chown` komutu sahip ve grubu birlikte alabilir; iki alan iki nokta üst üste ile ayrılır.

```
$ chown ogrenci:ogrenci veri/ham/olcum-01.csv
$ ls -l veri/ham/olcum-01.csv
-rw-r--r-- 1 ogrenci ogrenci 61 Jul 26 19:17 veri/ham/olcum-01.csv
$ chown :proje veri/ham/olcum-01.csv
$ ls -l veri/ham/olcum-01.csv
-rw-r--r-- 1 ogrenci proje 61 Jul 26 19:17 veri/ham/olcum-01.csv
```

Sahip kısmı boş bırakıldığında yalnızca grup değişir; bu biçim `chgrp` ile eşdeğerdir. İlk
komut sahibi değiştirmeye çalışmamıştır — verilen değer zaten mevcut sahiptir — bu yüzden
ayrıcalık gerektirmemiştir.

Ad yerine sayısal kimlik de yazılabilir. Ad çözümlemesinin çalışmadığı ortamlarda —
kurtarma kabuklarında veya yalın konteyner ortamlarında — tek seçenek budur.

Bir dosyanın sahipliğini başka bir dosyayla eşitlemek için `--reference` seçeneği vardır;
GNU araçlarına özgüdür ve ağacın tamamını bir örnek dosyaya göre düzeltmekte kullanılır.

#### Ağacın Gruba Açılması

Proje ağacı bir grupla paylaşıma hazırlanacaktır. `-R` seçeneği değişikliği özyinelemeli
uygular:

```
$ chgrp -R proje veri betik belge arsiv
$ ls -l
total 16
drwxr-xr-x 2 ogrenci proje 4096 Jul 26 19:11 arsiv
drwxr-xr-x 2 ogrenci proje 4096 Jul 26 19:03 belge
drwxr-xr-x 2 ogrenci proje 4096 Jul 26 18:49 betik
drwxr-xr-x 4 ogrenci proje 4096 Jul 26 19:08 veri
$ ls -l veri
total 8
lrwxrwxrwx 1 ogrenci proje   16 Jul 26 19:08 guncel.csv -> ham/olcum-03.csv
drwxr-xr-x 2 ogrenci proje 4096 Jul 26 19:10 ham
drwxr-xr-x 2 ogrenci proje 4096 Jul 26 19:03 islenmis
```

Ağacın tamamı artık `proje` grubuna aittir. Ancak grup sütununun değişmesi tek başına
paylaşım sağlamaz: grup izin bitleri hâlâ `r-x` düzeyindedir, yani grup üyeleri okuyabilir
ama yazamaz. Yazma yetkisi için grup bitlerinin de açılması gerekir — iki ayarın birbirinden
bağımsız olduğu, izin modelinin sık atlanan yanıdır.

Yeni oluşturulacak dosyaların da bu grubu alması ayrı bir sorundur ve `chgrp` ile çözülmez;
çözümü özel izin bitleri dersindedir.

#### Özyinelemede Sembolik Bağlar

Özyinelemeli değişiklikler ağacı dolaşır ve ağaçta sembolik bağ bulunabilir. Bağın hedefi
ağacın dışındaysa, "ağacın grubunu değiştir" komutu ağacın dışına taşabilir.

Varsayılan davranış taşmaz — değişiklik bağın kendisine uygulanır:

```
$ ls -l /tmp/bt/disarida.txt /tmp/bt/dizin/bag
-rw-r--r-- 1 ogrenci ogrenci  2 Jul 26 19:23 /tmp/bt/disarida.txt
lrwxrwxrwx 1 ogrenci ogrenci 15 Jul 26 19:23 /tmp/bt/dizin/bag -> ../disarida.txt
$ chgrp -R proje /tmp/bt/dizin
$ ls -l /tmp/bt/disarida.txt /tmp/bt/dizin/bag
-rw-r--r-- 1 ogrenci ogrenci  2 Jul 26 19:23 /tmp/bt/disarida.txt
lrwxrwxrwx 1 ogrenci proje   15 Jul 26 19:23 /tmp/bt/dizin/bag -> ../disarida.txt
```

Bağın grubu değişmiş, hedefin grubu değişmemiştir. Bağların kendi izin bitlerinin
kullanılmadığı önceki derste söylenmişti; buradaki değişiklik de bu yüzden pratik bir etki
doğurmaz — asıl önemli olan hedefe dokunulmamış olmasıdır.

Bağların izlenmesi açıkça istenirse sonuç değişir:

```
$ chgrp -R -L proje /tmp/bt/dizin
$ ls -l /tmp/bt/disarida.txt /tmp/bt/dizin/bag
-rw-r--r-- 1 ogrenci proje  2 Jul 26 19:23 /tmp/bt/disarida.txt
lrwxrwxrwx 1 ogrenci proje 15 Jul 26 19:23 /tmp/bt/dizin/bag -> ../disarida.txt
```

`-L` seçeneğiyle komut bağı izlemiş ve ağacın **dışındaki** dosyanın grubunu değiştirmiştir.
Ağaç içinde başkasının yazabildiği bir dizin varsa, oraya yerleştirilen bir bağ, özyinelemeli
komutu istenmeyen hedeflere yöneltebilir.

Üç seçenek ayrımı POSIX'te tanımlıdır ve akılda tutulması gereken şudur: `-P` bağı izlemez
ve özyinelemeli işlemlerde varsayılandır; `-L` her bağı izler; `-H` yalnızca komut satırında
doğrudan verilen bağları izler. Özyinelemeli izin ve sahiplik değişikliklerinde varsayılanı
değiştirmemek genel kuraldır.

Özyineleme olmadan, doğrudan argüman olarak verilen bir bağda davranış terstir: komut bağı
izler ve hedefin sahipliğini değiştirir. Bağın kendisini hedeflemek için `-h` seçeneği
kullanılır.

#### Doğrulama

Sahiplik değişiklikleri sessizdir; hata yoksa çıktı da yoktur. Bu nedenle sonuç ayrı bir
komutla doğrulanır. Gezinme dersindeki `ls -ld` biçimi burada gereklidir: bir dizinin
sahipliği sorulduğunda içeriği değil, dizinin kendi satırı okunmalıdır.

Ağacın tamamında beklenmedik sahiplik kalıp kalmadığı `find` ile sınanabilir; ölçüt
seçenekleri `-user` ve `-group` adlarını taşır ve eşleşmeyen dosyaları listeler.

Bir başka doğrulama noktası, üstveri değişikliğinin zaman damgalarına etkisidir. Gezinme
dersinde ayrılan üç zamandan yalnızca sonuncusu — üstveri değişiklik zamanı — güncellenir.
İçerik değişiklik zamanı korunduğu için `ls -lt` sıralaması etkilenmez.

#### Özet

- Sahip devri yalnızca kök kullanıcıya açıktır; kısıt, disk kotasının ve yetki devrinin
  kötüye kullanılmasını engeller.
- Dosyanın sahibi, grubu yalnızca kendi üyesi olduğu bir gruba çevirebilir.
- `chown` sahip ve grubu iki nokta üst üste ile ayırarak birlikte alır; sahip kısmı boş
  bırakıldığında yalnızca grup değişir.
- Grup sütununu değiştirmek paylaşım sağlamaz; grup izin bitleri ayrıca açılmalıdır.
- Özyinelemeli değişikliklerde sembolik bağlar varsayılan olarak izlenmez; `-L` ile
  izlendiklerinde işlem ağacın dışına taşabilir.
- Sahiplik değişikliği yalnızca üstveri zaman damgasını günceller; içerik zamanı korunur.

#### Sonraki Adım

Sahip devri gibi bazı işlemler kök yetkisi istiyor. Ancak kök hesabıyla oturum açıp çalışmak,
tek bir yazım hatasının tüm sistemi etkilemesi anlamına gelir. Sonraki ders yetki yükseltmeyi
ele alır: süper kullanıcının ne olduğu, yetkinin nasıl geçici ve sınırlı biçimde devredildiği
ve en az yetki ilkesinin uygulamada ne anlama geldiği.

### Yetki Yükseltme

Source: https://academia.sh/tr/kurslar/linuxa-giris/yetki-yukseltme

Süper kullanıcının denetim atlama ayrıcalığı, kullanıcı değiştirme ile komut başına yetki devri arasındaki fark, yetki devri politikasının yapısı ve en az yetki ilkesi.

Önceki derste sahip devri "Operation not permitted" ile reddedildi. Bazı işlemler kök
yetkisi ister; ama kök hesabıyla oturum açıp gün boyu çalışmak, her yazım hatasının tüm
sistemi etkileyebilmesi demektir.

Bu ders yetkinin nasıl **geçici ve sınırlı** biçimde alındığını ele alır. Konu bir komut
öğrenmekten çok bir ilke uygulamaktır: bir işlem için gereken en dar yetki, gereken en kısa
süre için alınır.

#### Süper Kullanıcı

Kullanıcı kimliği sıfır olan hesap **süper kullanıcıdır**. Ayrıcalığı, çekirdeğin izin
denetimlerinin çoğunu bu kimlik için atlamasından gelir: dosya izinlerine bakılmaz,
sahiplik değiştirilebilir, ayrıcalıklı bağlantı noktaları açılabilir, dosya sistemleri
bağlanabilir.

Ayrıcalık sınırsız değildir. Salt okunur takılmış bir dosya sistemine kök kullanıcı da
yazamaz; donanım düzeyinde yazma korumalı bir aygıta yazamaz. Bunlar izin denetimi
değildir, dolayısıyla atlanamazlar.

Kök hesabıyla sürekli çalışmanın üç somut sakıncası vardır:

**Hata yarıçapı.** Yanlış dizinde çalıştırılan yıkıcı bir komut, sıradan kullanıcıda kendi
dosyalarıyla sınırlı kalır; kök kullanıcıda sınır yoktur.

**Denetim izi.** Kök oturumunda yapılan işlem, hangi kişinin yaptığını kaydetmez. Birden çok
yöneticinin bulunduğu sistemlerde bu, sorunun kaynağını bulmayı olanaksızlaştırır.

**Yanlışlıkla kalıcı etki.** Kök hesabıyla oluşturulan dosyalar kök kullanıcıya ait olur.
Ev dizininde kök hesabıyla oluşturulmuş bir dosya, sıradan kullanıcı için erişilemez bir
artık bırakır.

Çoğu kurulumda kök hesabında parola tanımlı değildir ve doğrudan oturum açılamaz. Yetki,
aşağıdaki iki yoldan biriyle alınır.

#### Kullanıcı Değiştirme

`su` komutu, mevcut oturumun içinde **hedef kullanıcıya** geçer ve yeni bir kabuk açar.
Doğrulama için **hedef kullanıcının parolası** sorulur.

```
$ su -
Password: su: Authentication failure
```

Baştaki tire önemlidir: verildiğinde hedef kullanıcının oturum açma ortamı da kurulur —
ev dizini, `PATH` ve diğer ortam değişkenleri hedef hesabınkine ayarlanır. Verilmediğinde
kullanıcı değişir ama ortam eski kullanıcınınki kalır ve bu karışıklık kaynağıdır.

Yaklaşımın iki zayıflığı vardır. Birincisi, kök parolasının paylaşılmasını gerektirir;
parolayı bilen herkes her şeyi yapabilir ve parola değiştirildiğinde herkese yeniden
dağıtılması gerekir. İkincisi, açılan kabukta yapılan işlemler tek tek kaydedilmez.

#### Komut Başına Yetki Devri

`sudo` farklı bir modeldir: kullanıcı **kendi parolasıyla** doğrulanır ve bir politika
dosyasında tanımlanmış komutları, tanımlanmış bir hesabın yetkisiyle çalıştırır.

```
$ sudo id
[sudo] password for ogrenci: 
uid=0(root) gid=0(root) groups=0(root)
```

Komut kök kimliğiyle çalışmıştır. Parola sorulan hesap `ogrenci`'dir; kök parolası
bilinmemektedir ve gerekmemiştir.

Doğrulama bir süre önbelleklenir: aynı oturumda kısa süre içinde verilen ikinci komutta
parola yeniden sorulmaz. Önbellek `sudo -k` ile temizlenir; yukarıdaki örneklerde her
denemeden önce bu yapılmıştır.

İki modelin karşılaştırması:

| Ölçüt | `su` | `sudo` |
|---|---|---|
| Sorulan parola | Hedef hesabın | Kendi hesabının |
| Kapsam | Tüm kabuk oturumu | Tek komut |
| Sınırlanabilirlik | Yok, tam yetki | Politikayla komut düzeyinde |
| Kayıt | Oturum düzeyinde | Komut düzeyinde |
| Parola paylaşımı | Gerekir | Gerekmez |

#### Politikayı Okumak

Kullanıcının hangi komutları çalıştırabildiği sorulabilir:

```
$ sudo -l
[sudo] password for ogrenci: 
Matching Defaults entries for ogrenci on makine:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
    use_pty

User ogrenci may run the following commands on makine:
    (root) /usr/bin/id, /usr/bin/chown
```

Son satır politikanın özüdür. Parantez içindeki `root`, komutun hangi hesabın yetkisiyle
çalışacağını; devamı ise izin verilen komutların tam yollarını gösterir. Bu kullanıcı kök
yetkisiyle yalnızca iki programı çalıştırabilir.

Politika satırlarının genel biçimi dört parçalıdır: hangi kullanıcı, hangi makinede, hangi
hesap adına, hangi komutlar. Kullanıcı yerine grup adı da yazılabilir; yönetici yetkisi
çoğunlukla belirli bir gruba üyelik üzerinden verilir. Parola sorulmadan çalışmasına izin
veren bir işaret de vardır ve otomatik çalışan işler için kullanılır.

Politika dosyası doğrudan düzenlenmez. Sözdizimi hatası içeren bir politika, sistemde hiç
kimsenin yetki alamamasına yol açar; bu nedenle dosya, kaydetmeden önce sözdizimini
denetleyen özel bir araçla düzenlenir.

#### En Az Yetki İlkesi

Politikanın dar tutulması, izin verilmeyen bir komutta doğrudan görünür:

```
$ sudo cat /etc/shadow
[sudo] password for ogrenci: 
Sorry, user ogrenci is not allowed to execute '/usr/bin/cat /etc/shadow' as root on makine.
```

**En az yetki ilkesi**, her özneye görevini yapmak için gereken en dar yetkinin verilmesini
söyler. Uygulamada bu, politikada "tüm komutlar" yerine belirli komutların sayılması
demektir.

İlke, uygulanması göründüğünden zor bir ilkedir çünkü bazı komutlar dar görünüp geniş yetki
taşır:

**Kabuk açabilen komutlar.** Metin editörlerinin ve sayfalayıcıların çoğu, içinden komut
çalıştırma özelliği taşır. Kök yetkisiyle çalıştırılmasına izin verilen bir editör, kök
kabuğu vermeye eşdeğerdir.

**Argümanı serbest bırakılan komutlar.** Yukarıdaki politikada `chown` için argüman
kısıtlanmamıştır; kullanıcı istediği dosyanın sahibini değiştirebilir, dolayısıyla sistem
dosyalarının sahipliğini kendine geçirebilir. Politika dar görünse de sonucu geniştir.

**Dosya yazan komutlar.** Kök yetkisiyle herhangi bir dosyaya yazabilen bir komut, hesap
dosyasına satır ekleyerek yeni bir ayrıcalıklı kullanıcı oluşturabilir.

Politika yazarken sorulacak soru "bu komut zararlı mı" değil, **"bu komutla kök kabuğu elde
edilebilir mi"**dir.

#### Ortamın Temizlenmesi

Politika çıktısındaki `env_reset` ve `secure_path` ayarları, yetki devrinin sessiz ama
kritik bir parçasıdır. Komut yolu dersindeki gölgeleme, tam olarak burada saldırıya
dönüşürdü:

```
$ printf '#!/bin/sh\necho sahte kimlik\n' > /tmp/deneme/id
$ chmod +x /tmp/deneme/id
$ PATH="/tmp/deneme:$PATH"
$ id
sahte kimlik
$ sudo id
[sudo] password for ogrenci: 
uid=0(root) gid=0(root) groups=0(root)
```

Kullanıcının kendi oturumunda `id` adı sahte programa çözülmüştür. Yetkili çalıştırmada ise
gerçek program çalışmıştır: yetki devri aracı, kullanıcının `PATH` değerini yok sayıp
politikada tanımlı güvenli listeyi kullanmıştır.

Bu olmasaydı, "yalnızca `id` çalıştırabilir" biçimindeki bir politika hiçbir şey ifade
etmezdi; kullanıcı kendi yazdığı `id` adlı programı kök yetkisiyle çalıştırırdı. Ortam
değişkenlerinin de sıfırlanması aynı gerekçeye dayanır: kütüphane arama yolu gibi
değişkenler, çalıştırılan programın davranışını dışarıdan değiştirebilir.

Aynı gerekçe, sıradan kullanıcı için de geçerli bir alışkanlık doğurur: yetkili
çalıştırılacak komutlar tam yollarıyla yazılır.

#### Özet

- Süper kullanıcı, çekirdeğin izin denetimlerinin çoğunu atlar; salt okunur bağlama gibi
  izin dışı kısıtları atlamaz.
- Kök hesabıyla sürekli çalışmak hata yarıçapını büyütür, denetim izini yok eder ve
  erişilemez artıklar bırakır.
- `su` hedef hesabın parolasını ister ve tüm oturumu devreder; `sudo` kendi parolasını ister
  ve komut başına, politikayla sınırlı yetki verir.
- Politika dört parçadan oluşur: kullanıcı, makine, adına çalışılan hesap ve izin verilen
  komutlar.
- En az yetki ilkesinde ölçüt, komutun zararlı görünüp görünmemesi değil, o komutla kök
  kabuğu elde edilip edilemeyeceğidir.
- Yetki devri aracı `PATH` ve ortam değişkenlerini sıfırlar; aksi hâlde komut adı
  gölgelenerek politika etkisiz hâle getirilebilirdi.

#### Sonraki Adım

Yetki devri, bir komutu başka bir kimlikle çalıştırmanın dışarıdan yapılandırılan yoluydu.
Aynı etkinin dosyanın kendi üstverisine gömülü bir biçimi de vardır: kullanıcılar dersinde
görülen `-rwsr-xr-x` dizesindeki `s` harfi. Sonraki ders bu üç ek biti — çalıştıranın
kimliğini değiştiren iki bit ile dizinlerdeki silme yetkisini daraltan bir bit — ele alarak
konuyu kapatır.

### Özel İzin Bitleri

Source: https://academia.sh/tr/kurslar/linuxa-giris/ozel-izin-bitleri

Dokuz izin bitinin üstündeki üç bit; çalıştıranın kimliğini değiştiren setuid ve setgid, dizinlerde grup mirası ve silme yetkisini daraltan yapışkan bit.

Kullanıcılar dersinde bir ayrıntı açıkta bırakılmıştı: parola değiştirme programının izin
dizesinde, sahip sınıfının üçüncü konumunda `x` yerine `s` vardı.

```
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 72056 May 30  2024 /usr/bin/passwd
```

Bu ders o harfi ve iki kardeşini açıklar. Üç ek bit, dokuz izin bitinin çözemediği üç ayrı
sorunu çözer ve üçü de yetki yükseltmenin — bu kez dosyanın kendi üstverisine gömülü —
biçimleridir.

#### Dört Basamaklı Gösterim

İzin alanı aslında dokuz değil **on iki bittir**. Üç ek bit, sekizlik gösterimde soldan
dördüncü basamağı oluşturur:

| Bit | Sekizlik | Adı |
|---|---|---|
| setuid | 4000 | Kullanıcı kimliğini ayarla |
| setgid | 2000 | Grup kimliğini ayarla |
| yapışkan | 1000 | Sticky |

Tam değer `stat` ile okunabilir:

```
$ stat -c '%a %A %n' betik/ozet.sh paylasim
4755 -rwsr-xr-x betik/ozet.sh
3770 drwxrws--T paylasim
```

`4755` setuid artı `755`, `3770` ise setgid artı yapışkan artı `770` demektir. `chmod`
komutuna dört basamaklı değer verilebilir; simgesel biçimde karşılıkları `u+s`, `g+s` ve
`+t`'dir.

Ek bitler ayrı sütunlarda gösterilmez; var olan `x` konumlarının harfini değiştirirler:

| Konum | `x` açıkken | `x` kapalıyken |
|---|---|---|
| Sahip (setuid) | `s` | `S` |
| Grup (setgid) | `s` | `S` |
| Diğerleri (yapışkan) | `t` | `T` |

Büyük harf, ek bitin açık ama altındaki çalıştırma bitinin kapalı olduğunu bildirir. Bu
çoğunlukla bir yapılandırma hatasının işaretidir; yukarıdaki `drwxrws--T` çıktısı ise
istenmiş bir durumdur — dizinin "diğerleri" sınıfına hiç izin verilmemiştir.

#### setuid: Çalıştıranın Kimliğini Değiştirmek

Normalde bir program, onu çalıştıran kullanıcının kimliğiyle çalışır. **setuid** biti açık
bir çalıştırılabilir dosya ise, çalıştıranın değil **sahibinin** kimliğiyle çalışır.

Parola değiştirme programı bu yüzden işaretlidir. Program kök kullanıcıya aittir ve setuid
biti açıktır; sıradan bir kullanıcı onu çalıştırdığında süreç kök yetkisiyle çalışır ve
yalnızca kök tarafından yazılabilen parola dosyasını güncelleyebilir. Kullanıcı dosyaya
doğrudan erişemez; erişimi olan, denetimli bir programa erişir.

Model, yetki yükseltme dersindeki politikayla aynı ilkeyi izler ama yetkiyi dışarıdan
tanımlanan bir politikada değil, dosyanın üstverisinde tutar. Buradan iki sonuç çıkar.

**setuid programlar saldırı yüzeyidir.** Böyle bir programdaki her hata, ayrıcalık
kazanmaya dönüşebilir. Bu nedenle setuid programlar az sayıda tutulur, dar iş yapar ve
girdilerini titizlikle denetler. Sistem üzerindeki setuid dosyaların listesi `find` ile
çıkarılabilir; ölçüt seçeneği `-perm` adını taşır ve düzenli denetimlerin standart
adımlarından biridir.

**Kabuk betiklerinde yok sayılır.** Çekirdek, yorumlayıcıyla çalıştırılan dosyalarda bu
biti uygulamaz:

```
$ printf '#!/bin/sh\nid -un\n' > /tmp/kimlik.sh
$ chmod 4755 /tmp/kimlik.sh
$ ls -l /tmp/kimlik.sh
-rwsr-xr-x 1 ogrenci ogrenci 17 Jul 26 19:31 /tmp/kimlik.sh
```

Başka bir kullanıcı çalıştırdığında sonuç değişmez:

```
$ id -un
yedek
$ /tmp/kimlik.sh
yedek
```

Bit açık görünmesine karşın süreç `yedek` kimliğiyle çalışmıştır. Nedeni bir yarış
durumudur: çekirdek dosyayı açıp yorumlayıcıyı çalıştırana kadar geçen sürede dosya
değiştirilebilir ve ayrıcalıklı yorumlayıcı başka bir betiği çalıştırabilirdi. Bu kapı,
biti yok sayarak kapatılmıştır.

#### setgid: Dosyalarda ve Dizinlerde

**setgid** biti çalıştırılabilir dosyalarda setuid'in grup karşılığıdır: süreç, çalıştıranın
değil dosyanın grubuyla çalışır.

Dizinlerde ise bambaşka ve çok daha sık kullanılan bir anlam taşır: **dizinde oluşturulan
yeni dosyalar, oluşturanın birincil grubunu değil dizinin grubunu alır.**

Sahiplik dersinde bırakılan sorun tam olarak buydu. Ağacın grubu değiştirilmişti, ama yeni
dosyalar yine kullanıcının birincil grubuyla oluşuyordu.

```
$ mkdir -p paylasim
$ chgrp proje paylasim
$ chmod 770 paylasim
$ ls -ld paylasim
drwxrwx--- 2 ogrenci proje 4096 Jul 26 19:30 paylasim
$ touch paylasim/deneme-1.csv
$ ls -l paylasim
total 0
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:30 deneme-1.csv
```

Dizin `proje` grubuna ait olmasına karşın, içinde oluşan dosya `ogrenci` grubunu almıştır;
grup üyeleri bu dosyayı yazamaz. setgid biti eklendiğinde davranış değişir:

```
$ chmod g+s paylasim
$ ls -ld paylasim
drwxrws--- 2 ogrenci proje 4096 Jul 26 19:30 paylasim
$ touch paylasim/deneme-2.csv
$ ls -l paylasim
total 0
-rw-r--r-- 1 ogrenci ogrenci 0 Jul 26 19:30 deneme-1.csv
-rw-r--r-- 1 ogrenci proje   0 Jul 26 19:30 deneme-2.csv
```

Bitten önce oluşan dosya eski grubunu korumuş, sonra oluşan dosya dizinin grubunu almıştır.
Bit ayrıca yeni oluşturulan **alt dizinlere de kopyalanır**; böylece ağacın tamamında miras
sürer.

Grup paylaşımının çalışması için üç ayarın birlikte yapılması gerekir: dizinin grubu, grup
yazma izni ve setgid biti. Üçünden biri eksikse paylaşım çalışmaz ve eksikliğin belirtisi
her seferinde farklı görünür.

Yeni dosyaların grup yazma iznini de alması için maske de düzenlenmelidir; izin bitleri
dersindeki `022` maskesi grup yazmasını kapatır. Paylaşılan dizinlerde çalışırken maske
`002` yapılır.

#### Yolun Geçilebilir Olması

Paylaşım, dizin izinleriyle bitmez. Yol çözümlemesi dersindeki kural burada devreye girer:
paylaşılan dizine ulaşmak için **yol üzerindeki her dizinde geçiş izni** gerekir.

```
$ chgrp proje ~
$ chmod 710 ~
$ ls -ld ~
drwx--x--- 5 ogrenci proje 4096 Jul 26 19:13 /home/ogrenci
```

`710` değeri sahibe tam yetki, gruba yalnızca geçiş izni verir. Grup üyeleri ev dizininin
içeriğini **listeleyemez** ama içinden geçebilir:

```
$ id -un
yedek
$ ls /home/ogrenci
ls: cannot open directory '/home/ogrenci': Permission denied
$ ls /home/ogrenci/paylasim
deneme-1.csv  deneme-2.csv
```

İzin bitleri dersindeki "okuma var, geçiş yok" örneğinin tersi burada gerçek bir
yapılandırmaya dönüşmüştür: ev dizininin içeriği gizli kalırken, adı bilinen alt dizin
paylaşılabilir.

#### Yapışkan Bit

Paylaşılan dizin artık çalışıyor, ama izin bitleri dersinde bırakılan boşluk açık: dizinde
yazma izni olan kullanıcı, içindeki **her** dosyayı silebilir.

```
$ id -un
yedek
$ ls -l
total 0
-rw-rw-r-- 1 ogrenci ogrenci 0 Jul 26 19:31 deneme-1.csv
-rw-rw-r-- 1 ogrenci proje 0 Jul 26 19:31 deneme-2.csv
$ rm deneme-1.csv
$ ls -l
total 0
-rw-rw-r-- 1 ogrenci proje 0 Jul 26 19:31 deneme-2.csv
```

`yedek` kullanıcısı, sahibi olmadığı bir dosyayı silmiştir. Silme dersindeki tanım bunu
açıklar: silmek dizin girdisini kaldırmaktır ve aranan izin dizinin yazma iznidir.

**Yapışkan bit** bu kuralı daraltır. Bit açık bir dizinde bir girdiyi yalnızca üç taraf
kaldırabilir: dosyanın sahibi, dizinin sahibi ve kök kullanıcı.

```
$ chmod +t paylasim
$ ls -ld paylasim
drwxrws--T 2 ogrenci proje 4096 Jul 26 19:31 paylasim
```

Aynı kullanıcı aynı işlemi yeniden dener:

```
$ rm deneme-2.csv
rm: cannot remove 'deneme-2.csv': Operation not permitted
$ touch yedek-notu.csv
$ ls -l
total 0
-rw-rw-r-- 1 ogrenci proje 0 Jul 26 19:31 deneme-2.csv
-rw-r--r-- 1 yedek   proje 0 Jul 26 19:31 yedek-notu.csv
$ rm yedek-notu.csv
$ ls -l
total 0
-rw-rw-r-- 1 ogrenci proje 0 Jul 26 19:31 deneme-2.csv
```

Başkasının dosyasını silmek engellenmiş, kendi oluşturduğu dosyayı silmek engellenmemiştir.
Yazma izni de kaybolmamıştır — dizine yeni dosya eklenebilmektedir. Bit yalnızca **silme ve
yeniden adlandırma** işlemlerini daraltır.

Bu, sistemdeki geçici dizinlerin standart yapılandırmasıdır:

```
$ ls -ld /tmp
drwxrwxrwt 1 root root 4096 Jul 26 19:24 /tmp
```

`rwxrwxrwt` dizesi şunu söyler: herkes yazabilir, ama herkes yalnızca kendi dosyasını
silebilir. Yapışkan bit olmasaydı, geçici dizin herkesin birbirinin dosyasını
silebildiği bir alan olurdu.

#### Özet

- İzin alanı on iki bittir; ek üç bit sekizlik gösterimde dördüncü basamağı oluşturur.
- Ek bitler ayrı sütun almaz, `x` konumlarının harfini değiştirir; büyük harf altındaki
  çalıştırma bitinin kapalı olduğunu bildirir.
- setuid işaretli çalıştırılabilir dosya, çalıştıranın değil sahibinin kimliğiyle çalışır;
  kabuk betiklerinde yarış durumu nedeniyle yok sayılır.
- Dizinlerde setgid, yeni dosyaların dizinin grubunu almasını sağlar ve alt dizinlere
  kopyalanır; grup paylaşımı için grup, yazma izni ve bu bit birlikte gerekir.
- Paylaşılan dizine erişim için yol üzerindeki her dizinde geçiş izni gerekir; `710` değeri
  listelemeden geçiş verir.
- Yapışkan bit, dizindeki bir girdiyi yalnızca dosyanın sahibinin, dizinin sahibinin ve kök
  kullanıcının kaldırabilmesini sağlar; geçici dizinlerin standart yapılandırmasıdır.

#### Sonraki Adım

Kimlik, izin ve yetki modeli tamamlandı; proje ağacı bir grupla güvenli biçimde
paylaşılabilir durumda. Geriye sistemin kendisiyle ilgili son bir katman kalıyor: bu ağaçta
çalışmak için kullanılan araçlar sisteme nasıl geldi, nasıl güncellenir ve nasıl
kaldırılır? Sonraki konu paket yöneticisi kavramıyla başlar ve kursu, ağacı düzenlemek için
gereken metin editörleriyle kapatır.

## Paket Yönetimi ve Editörler

Depo, bağımlılık ve sürüm çözümleme; paket kurma, kaldırma ve doğrulama işlemleri, depo güven modeli ve terminal metin editörleri.

### Paket Yöneticisi Kavramı

Source: https://academia.sh/tr/kurslar/linuxa-giris/paket-yoneticisi-kavrami

Paketin dosya kümesi ve üstveriden oluşması, kurulu paket veritabanının işlevi, bağımlılık çözümlemesinin kısıt problemi olarak yapısı ve sürüm karşılaştırma kuralları.

Kurs boyunca kullanılan araçların hepsi sistemde hazır bulundu. Bunların oraya nasıl geldiği,
nasıl güncellendiği ve nasıl kaldırıldığı sorulmadı.

Soru göründüğünden zordur. Bir programı kurmak, dosyalarını kopyalamaktan ibaret değildir:
çalıştırılabilir dosya bir dizine, kütüphaneleri başka bir dizine, yapılandırması `/etc`
altına, belgeleri kılavuz dizinine gider. Dizin hiyerarşisi dersindeki yerleşim standardı
tam olarak bu dağılımı tanımlıyordu. Elle yapıldığında hangi dosyanın hangi programa ait
olduğu kaydedilmez ve kaldırma işlemi olanaksızlaşır.

#### Paket Nedir

**Paket**, kurulacak dosyaları ve bu dosyalar hakkındaki üstveriyi bir arada taşıyan
arşivdir. Yapısı, arşivleme dersindeki biçime benzer: dosya ağacı artı başlık bilgisi. Fark,
başlığın kurulum kararları için okunmasıdır.

Üstverinin taşıdığı bilgiler paket yöneticisi ailesine göre adlandırma farkları gösterse de
alanlar ortaktır:

| Alan | İşlevi |
|---|---|
| Ad | Paketin kimliği |
| Sürüm | Hangi yayın olduğu |
| Mimari | Hangi işlemci ailesi için derlendiği |
| Bağımlılıklar | Çalışması için gereken diğer paketler |
| Çakışmalar | Aynı anda kurulu olamayacağı paketler |
| Sağladıkları | Karşıladığı soyut yetenek adları |
| Özetler | Her dosyanın içerik özeti |
| Kurulum betikleri | Kurulum öncesi ve sonrası çalışacak adımlar |

Son iki alan sık atlanır ama belirleyicidir. Özetler, kurulu dosyaların sonradan
değiştirilip değiştirilmediğinin sınanmasını sağlar — dosya aktarımı dersindeki doğrulama
yönteminin sistem ölçeğine taşınmış hâlidir. Kurulum betikleri ise dosya kopyalamanın
yetmediği durumları — kullanıcı hesabı açma, servis kaydı, veritabanı düzenleme — kapsar ve
kök yetkisiyle çalıştıkları için paket güveninin merkezinde dururlar.

#### Kurulu Paket Veritabanı

Paket yöneticisinin ikinci bileşeni, sistemde kurulu her paketin kaydını tutan yerel bir
veritabanıdır. Kayıt, paketin üstverisini ve kurduğu dosyaların tam listesini içerir.

Bu liste olmadan üç işlem yapılamaz:

**Kaldırma.** Hangi dosyaların silineceği bilinemez; elle kurulan yazılım, kaldırıldığında
sistemde artık bırakır.

**Yükseltme.** Eski sürümün hangi dosyalarının yenisinde bulunmadığı bilinemez; artık
dosyalar birikir.

**Sahiplik sorgusu.** Sistemdeki bir dosyanın hangi pakete ait olduğu sorulamaz; bu sorgu,
bir arızayı hangi paketin sorumluluğuna yazacağını belirlemekte kullanılır.

Veritabanının bir başka sonucu, **elle değiştirilmiş dosyaların** ayırt edilebilmesidir.
Yapılandırma dosyaları paketle gelir ama yönetici tarafından değiştirilir; yükseltmede bu
değişikliklerin korunması gerekir. Paket yöneticileri, dosyanın özetini kayıttakiyle
karşılaştırarak değişip değişmediğini anlar ve değişmişse yükseltmede üzerine yazmak yerine
kullanıcıya sorar.

#### Bağımlılıklar Neden Vardır

Bağımlılık soyut bir kavram değildir; çalıştırılabilir dosyaların kendisinde görülebilir:

```
$ ldd /usr/bin/ls
	linux-vdso.so.1 (0x0000ffff88cce000)
	libselinux.so.1 => /lib/aarch64-linux-gnu/libselinux.so.1 (0x0000ffff88be0000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff88a20000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffff88c80000)
	libpcre2-8.so.0 => /lib/aarch64-linux-gnu/libpcre2-8.so.0 (0x0000ffff88970000)
```

Listeleme komutu tek başına çalışmaz: standart C kütüphanesine, güvenlik etiketleri
kütüphanesine ve düzenli ifade kütüphanesine bağlıdır. Parantez içindeki sayılar
kütüphanelerin o çalıştırmadaki yükleme adresleridir ve her çağrıda değişir; kütüphane
adları değişmez. Bu kütüphaneler ayrı paketlerde
gelir. Bilgisayarlar Nasıl Çalışır kursundaki bağlama ve yükleme dersi bu ilişkiyi
tanımlamıştı; paket bağımlılıkları o ilişkinin dağıtım düzeyindeki karşılığıdır.

Paylaşılan kütüphane kullanmanın gerekçesi tekrarı önlemektir: yüzlerce program aynı
kütüphanenin ayrı kopyasını taşımaz. Bedeli, kurulumun bir bağımlılık çizgesine
dönüşmesidir.

**Sağlanan yetenek** kavramı bu çizgeyi esnetir. Bir paket, somut adının yanında soyut bir
yetenek adı da sağlayabilir; başka paketler somut ada değil bu yeteneğe bağlanır. Böylece
aynı işi yapan farklı gerçekleştirimler birbirinin yerine geçebilir. Kabuk dersindeki
`/bin/sh` örneğinin paketleme düzeyindeki karşılığıdır: bağımlılık bir role kurulur, role
hangi programın atandığı sistemin kararıdır.

#### Çözümleme Bir Kısıt Problemidir

Bir paketin kurulması istendiğinde çözülmesi gereken soru şudur: kurulu paket kümesine
hangi paketler eklenirse tüm bağımlılıklar sağlanır ve hiçbir çakışma oluşmaz?

Bu bir arama problemidir. Küçük bir örnek yapısını gösterir:

| Paket | Bağımlılık | Çakışma |
|---|---|---|
| `cizim` 2.0 | `grafik` ≥ 3 | — |
| `rapor` 1.4 | `grafik` ≤ 2 | — |
| `grafik` 1.8 | — | — |
| `grafik` 2.9 | — | — |
| `grafik` 3.1 | — | — |

`cizim` ile `rapor` aynı sistemde kurulamaz: biri `grafik` kütüphanesinin üçüncü sürümünü,
diğeri en çok ikinci sürümünü ister. Çözümleyici bunu bildirir ve kullanıcıdan seçim
yapmasını bekler. Gerçek sistemlerde bu çizge on binlerce düğüm taşır ve kısıtlar
kesişimler, alternatifler ve sürüm aralıklarıyla karmaşıklaşır.

Çözümlemenin sonucu üç durumdan biridir: bir çözüm bulunur ve işlem listesi sunulur; çözüm
yoktur ve çakışma bildirilir; ya da birden çok çözüm vardır ve yöneticinin tercih kuralları
— hangi depo öncelikli, hangi sürüm yeğlenir — devreye girer.

Bu nedenle kurulum komutları, işlemi yapmadan önce **ne yapacaklarını listeler ve onay
ister**. Liste yalnızca istenen paketi değil, sürüklediği tüm bağımlılıkları ve kaldırılması
gerekenleri içerir; okunmadan onaylanmamalıdır.

#### Sürüm Karşılaştırma

Bağımlılıklar "en az şu sürüm" biçiminde kısıt koyduğuna göre, sürümlerin karşılaştırılabilir
olması gerekir. Karşılaştırma sözlük sırasıyla yapılamaz:

- `1.10` sürümü `1.9`'dan **büyüktür**, ama metin olarak karşılaştırılırsa küçük görünür.
- `2.0` ile `2.0.0` çoğu kuralda eşit sayılır.
- `1.0-beta` sürümü `1.0`'dan **küçüktür**; harf içeren ekler yayın öncesi anlamına gelir.

Bu yüzden her paket yöneticisi ailesinin tanımlı bir karşılaştırma algoritması vardır: sürüm
dizesi sayısal ve harfli parçalara bölünür, sayısal parçalar sayı olarak, harfli parçalar
sıralı olarak karşılaştırılır.

Bir de sıralamayı elle bozma gereği doğar. Bir yazılımın sürüm numaralandırma düzeni
değiştiğinde, yeni sürüm eskisinden küçük görünebilir. Bunun için sürüm dizesinin önüne,
karşılaştırmada her şeyden önce bakılan bir sayı eklenir; bu sayı arttığında sonraki tüm
karşılaştırmalar yeni düzeni kazanır.

#### Paket Yöneticisi Sınıfları

Araçlar iki düzeyde çalışır ve ayrım her ailede vardır.

**Alt düzey araç** tek bir paket dosyasıyla ilgilenir: açar, dosyaları yerleştirir,
veritabanına kaydeder. Bağımlılık **çözmez**; eksik bağımlılık varsa hata verir. Kurulu
paketleri sorgulama işlemleri de bu düzeydedir.

**Üst düzey araç** depoları bilir, bağımlılıkları çözer, indirir ve alt düzey aracı çağırır.
Kullanıcının gündelik olarak kullandığı araç budur.

Ayrım pratik bir sonuç doğurur: elde bir paket dosyası varsa ve alt düzey araçla kurulursa,
bağımlılıklar eksik kalabilir. Doğru yaklaşım, dosyayı üst düzey araca vermektir; böylece
eksik bağımlılıklar depodan tamamlanır.

Bir de sistem paket yöneticisinin dışında kalan bir alan vardır: programlama dillerinin
kendi paket yöneticileri. İkisi ayrı veritabanı tutar ve birbirinden habersizdir. Aynı
kütüphane her ikisiyle de kurulursa hangi kopyanın kullanıldığı belirsizleşir. Yaygın
uygulama, dil düzeyindeki paketleri sistem dizinlerine değil projeye veya kullanıcıya özgü
bir alana kurmaktır.

#### Özet

- Paket, kurulacak dosyaları ve üstveriyi taşıyan arşivdir; üstveri bağımlılık, çakışma,
  özet ve kurulum betiği bilgilerini içerir.
- Kurulu paket veritabanı, kaldırma, yükseltme ve dosya sahipliği sorgusunu mümkün kılan
  kayıttır.
- Bağımlılıklar paylaşılan kütüphanelerin somut sonucudur; soyut yetenek adları farklı
  gerçekleştirimlerin birbirinin yerine geçmesini sağlar.
- Kurulum bir kısıt problemidir; çözüm olmayabilir veya birden çok olabilir, bu yüzden
  araçlar işlem listesini onaya sunar.
- Sürüm karşılaştırması sözlük sırasıyla yapılamaz; sürüm dizesi sayısal ve harfli parçalara
  bölünerek karşılaştırılır.
- Alt düzey araç tek paketle ilgilenir ve bağımlılık çözmez; üst düzey araç depoları bilir
  ve çözümlemeyi yapar.

#### Sonraki Adım

Kavramlar kurulduğuna göre işlemlere geçilebilir. Sonraki ders, ailesi ne olursa olsun her
paket yöneticisinde karşılığı bulunan işlem kümesini tanıtır: dizin güncelleme, kurma,
kaldırma, yapılandırmayla birlikte kaldırma, sorgulama ve doğrulama — ve bu işlemlerin
hangilerinin geri alınabilir olduğunu.

### Paket Kurma ve Kaldırma

Source: https://academia.sh/tr/kurslar/linuxa-giris/paket-kurma-ve-kaldirma

Paket yöneticisi ailelerinde ortak olan işlem sınıfları, işlem listesinin okunması, kaldırma ile yapılandırmayla birlikte kaldırmanın farkı ve paket dışı kurulum alanları.

Önceki ders paket kavramını ve bağımlılık çözümlemesini kurdu. Bu ders gündelik işlemlere
iner.

Komut adları paket yöneticisi ailesine göre değişir; bu kurs belirli bir aracın söz dizimini
öğretmez. Öğretilen şey, **hangi işlemin ne yaptığı ve hangi sırayla yapılacağıdır**; bu
bilgi taşınabilir, komut adları taşınabilir değildir. Bir sistemde karşılıklarını bulmak
için, yardım kaynakları dersindeki kılavuz sayfaları yeterlidir.

#### İşlem Sınıfları

Paket yöneticilerinin çoğunda şu işlemlerin karşılığı bulunur:

| İşlem | Yaptığı |
|---|---|
| Dizin güncelleme | Depolardaki paket listesinin yerel kopyasını tazeler |
| Arama | Ada ve açıklamaya göre paket arar |
| Gösterme | Bir paketin üstverisini yazdırır |
| Kurma | Paketi ve bağımlılıklarını kurar |
| Kaldırma | Paketin dosyalarını siler, yapılandırmayı bırakır |
| Tümüyle kaldırma | Yapılandırma dosyalarını da siler; her ailede ayrı bir işlem değildir |
| Artıkları temizleme | Bağımlılık olarak kurulmuş, artık gerekmeyen paketleri kaldırır |
| Yükseltme | Kurulu paketleri yeni sürümlerine geçirir |
| Dosya listesi | Bir paketin kurduğu dosyaları listeler |
| Sahiplik sorgusu | Bir dosyanın hangi pakete ait olduğunu bulur |
| Doğrulama | Kurulu dosyaları kayıttaki özetlerle karşılaştırır |

İlk satır, sıranın başında olması gereken işlemdir. Yerel dizin, deponun içeriğinin bir
kopyasıdır ve eskiyebilir. Eskimiş dizinle yapılan kurulum, artık depoda bulunmayan bir
sürümü indirmeye çalışır ve başarısız olur. Bu yüzden kurulum, dizin güncellemesinin
ardından yapılır.

Son satır, önceki derste anlatılan özetlerin kullanıldığı yerdir: kurulu bir dosyanın
içeriği kayıttakinden farklıysa, dosya ya elle değiştirilmiştir ya da bozulmuştur. Bir
arıza araştırmasında ilk sorulacak sorulardan biri budur.

#### İşlem Listesini Okumak

Kurma ve kaldırma komutları, işlemi yapmadan önce ne olacağını listeler ve onay ister. Liste
üç bölümden oluşur: kurulacaklar, kaldırılacaklar ve yükseltilecekler.

Onaylamadan önce denetlenecek üç nokta vardır:

**Kaldırılacaklar listesi boş mu?** Bir paket kurmak için başka paketlerin kaldırılması
gerekiyorsa, çakışan bir bağımlılık vardır. Liste beklenmedik adlar içeriyorsa işlem iptal
edilmelidir.

**Sürüklenen bağımlılıkların sayısı beklenen düzeyde mi?** Küçük bir aracın yüzlerce paket
sürüklemesi, yanlış paketin seçildiğini veya çok kapsamlı bir üst paketin istendiğini
gösterebilir.

**Paketler beklenen depodan mı geliyor?** Birden çok depo yapılandırılmışsa, aynı paket
farklı kaynaklardan gelebilir. Kaynak, sonraki dersin konusudur.

Kurulum işlemleri kök yetkisi ister; sistem dizinlerine yazar ve kurulum betiklerini
ayrıcalıklı çalıştırır. Yetki yükseltme dersindeki ilke burada doğrudan uygulanır: paket
kurma yetkisi vermek, kurulum betikleri kök olarak çalıştığı için, kök yetkisi vermeye
yakındır.

#### Kaldırma ve Tümüyle Kaldırma

İki kaldırma işlemi arasındaki fark yapılandırma dosyalarındadır.

**Kaldırma**, paketin getirdiği dosyaları siler ama `/etc` altındaki yapılandırmayı bırakır.
Gerekçe şudur: yapılandırma dosyaları yönetici tarafından düzenlenmiştir ve paket
kaldırılıp yeniden kurulduğunda bu emeğin korunması beklenir.

**Tümüyle kaldırma**, yapılandırmayı da siler. Paketin bir daha kullanılmayacağı kesinse ve
temiz bir durum isteniyorsa bu seçilir.

Hiçbiri kullanıcı verisini silmez. Ev dizinlerindeki ayarlar ve `/var` altındaki veriler
paket yöneticisinin kaydında değildir; paket onları oluşturmamıştır, silmez de. Bir servisi
kaldırdıktan sonra verisinin de gitmesi isteniyorsa bu ayrı ve bilinçli bir adımdır.

Bağımlılık olarak kurulmuş paketler ayrı işaretlenir. Bir paket kaldırıldığında, yalnızca
onun için getirilmiş bağımlılıklar sistemde kalır ama "artık" olarak işaretlenir; temizleme
işlemi bunları toplar. Bu ayrım olmasaydı sistem, zamanla hiçbir şeyin kullanmadığı
paketlerle dolardı.

#### Yükseltme

Yükseltmenin iki kapsamı vardır ve karıştırılmaları risklidir.

**Tek paket yükseltme**, yalnızca adı verilen paketi yeniler. Bağımlılıkları da yeni sürüm
gerektiriyorsa onlar da yükseltilir.

**Sistem yükseltme**, kurulu tüm paketleri depodaki güncel sürümlere geçirir. Depo tutarlı
bir bütün olarak yayımlandığı için önerilen yol budur.

Aradaki tehlikeli bölge **kısmi yükseltmedir**: bazı paketler yeni, bazıları eski
bırakıldığında, birbirine bağlı kütüphanelerin sürümleri uyuşmayabilir. Depo bakımcıları
paketleri birlikte sınar; ayrı ayrı yükseltilmiş bir küme sınanmamış bir bileşimdir.

Bir sürümü kasıtlı olarak geride tutmak gerekiyorsa, paket yöneticileri bunun için bir
**sabitleme** düzeneği sunar: paket veya sürüm işaretlenir ve yükseltmelerin dışında
bırakılır. Sabitleme, kısmi yükseltme riskini bilinçli olarak üstlenmektir ve gerekçesi
belgelenmelidir.

Sürüm düşürme her ailede aynı ölçüde desteklenmez; bir ailede ayrı bir komutu varken
ötekinde sürümün elle belirtilmesi gerekir. Kurulum betikleri ileri yönde çalışacak biçimde
yazılır; veri biçimini dönüştüren bir yükseltmeden sonra eski sürüme dönmek veriyi
okunamaz bırakabilir.

#### Paket Yöneticisinin Dışı

Her yazılım depoda bulunmaz. Yerleşim standardı bu durum için ayrılmış bir alan tanımlar:
`/usr/local`, paket yöneticisinin dokunmadığı, yerel olarak kurulan yazılımların yeridir.
Aynı ayrımın kullanıcı düzeyindeki karşılığı ev dizini altındaki yerel dizindir ve kök
yetkisi gerektirmez.

```
$ mkdir -p ~/.local/bin
$ chmod 755 ~/.local/bin/proje-yedek
$ cat ~/.local/bin/proje-yedek
#!/bin/sh
# Proje agacini tarihli bir arsive alir.
tar -czf "$HOME/proje/arsiv/proje-$(date +%Y%m%d).tar.gz" -C "$HOME" proje/veri proje/betik proje/belge
```

Bu dizin, oturum açılışında okunan yapılandırma tarafından arama listesine eklenir:

```
$ echo "$PATH"
/home/ogrenci/proje/betik:/home/ogrenci/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ command -v proje-yedek
/home/ogrenci/.local/bin/proje-yedek
```

Araç artık her yerden çağrılabilir:

```
$ proje-yedek
$ ls -l proje/arsiv
total 84
-rw-r--r-- 1 ogrenci ogrenci 11665 Jul 26 19:35 proje-20260726.tar.gz
-rw-r--r-- 1 ogrenci proje   51200 Jul 26 19:10 veri.tar
-rw-r--r-- 1 ogrenci proje   11330 Jul 26 19:10 veri.tar.gz
-rw-r--r-- 1 ogrenci proje    4416 Jul 26 19:10 veri.tar.xz
```

Arşivleme dersindeki komut, tarihli bir adla ve tek çağrıyla çalışan bir araca dönüşmüştür.

Bu yaklaşımın sınırı, önceki dersteki veritabanı tartışmasıdır. Tek dosyalık bir araçta
kaldırma işlemi bir `rm` komutudur. Onlarca dosyayı altı ayrı dizine dağıtan bir yazılımda
ise hangi dosyanın kime ait olduğu kaydedilmediği için kaldırma güvenilir biçimde
yapılamaz. Paket yöneticisinin çözdüğü sorun tam olarak budur.

Ölçüt şudur: tek dosyalık ve bağımlılıksız araçlar yerel dizine kurulabilir; bağımlılığı
olan ve sisteme dağılan yazılımlar paket yöneticisinden geçmelidir. Aradaki durumlar için,
yazılımı kendi dizinine kapatan ve tek bir bağla arama listesine bağlayan yerleşim tercih
edilir; kaldırma o dizini silmeye indirgenir.

#### Özet

- Paket yöneticileri farklı komut adlarıyla aynı işlem sınıflarını sunar; taşınabilir olan
  işlem bilgisidir, komut adı değil.
- Kurulum, yerel paket dizininin güncellenmesinden sonra yapılır; eskimiş dizin artık
  bulunmayan sürümleri indirmeye çalışır.
- İşlem listesinde kaldırılacaklar, sürüklenen bağımlılık sayısı ve paketlerin kaynağı
  denetlenir.
- Kaldırma yapılandırmayı bırakır, tümüyle kaldırma siler; ikisi de kullanıcı verisine
  dokunmaz.
- Kısmi yükseltme, birlikte sınanmamış bir sürüm bileşimi üretir; sabitleme bu riskin
  bilinçli üstlenilmesidir.
- Paket dışı kurulum, tek dosyalık ve bağımlılıksız araçlar için uygundur; sisteme dağılan
  yazılımlarda kaldırma kaydı olmadığı için güvenilir değildir.

#### Sonraki Adım

Paketlerin geldiği yer bu derste "depo" olarak anıldı ama tanımlanmadı. Depo bir dosya
sunucusundan ibaret değildir: bir dizin dosyası, bu dosyanın imzası ve paketlerin özetleri
birlikte bir güven zinciri kurar. Sonraki ders bu zinciri açar ve yeni bir deponun sisteme
eklenmesinin neden bir güven kararı olduğunu gösterir.

### Depo Yapılandırması

Source: https://academia.sh/tr/kurslar/linuxa-giris/depo-yapilandirmasi

Depo tanımının bileşenleri, imzalı dizin ve paket özetlerinden oluşan güven zinciri, anahtar parmak izinin doğrulanması ve depo önceliğinin sonuçları.

Önceki iki ders paketlerin "depodan" geldiğini söyledi ama deponun ne olduğunu tanımlamadı.
Depo bir dosya sunucusundan ibaret değildir; olsaydı, indirilen paketin doğru paket olduğunu
söyleyecek hiçbir şey bulunmazdı.

Bu ders deponun yapısını ve üzerine kurulu güven zincirini ele alır. Zincir, dosya aktarımı
dersindeki özet doğrulaması ile aynı dersin şifreli kabuk bölümünde kurulan parmak izi
onayının birleşimidir;
ikisi de burada tek bir düzenekte buluşur.

#### Depo Tanımı

Sisteme bir depo tanıtmak, ona en az şu bilgileri vermektir:

| Alan | Anlamı |
|---|---|
| Adres | Dosyaların indirileceği temel konum |
| Yayın | Deponun hangi sürüm dalını sunduğu |
| Bileşen | Depo içindeki alt bölüm (örneğin özgür yazılım ayrımı) |
| Mimari | Hangi işlemci ailesi için paket isteneceği |
| Anahtar | Deponun imzalarını doğrulayacak açık anahtar |

Tanımlar `/etc` altında, dizin hiyerarşisi dersinde anlatılan "yapılandırma metin
dosyalarında durur" ilkesine uygun biçimde tutulur. Adlandırma ve söz dizimi paket
yöneticisi ailesine göre değişir, alanlar değişmez.

Adres alanının bir sonucu, aynı içeriğin birden çok sunucudan sunulabilmesidir: **yansılar**.
Yansı, deponun birebir kopyasını taşıyan bağımsız bir sunucudur ve indirmeyi hızlandırmak
için kullanılır. Yansının içeriğini doğrulamak, aşağıdaki zincirin var olma nedenidir; aksi
hâlde her yansıya ayrı ayrı güvenmek gerekirdi.

#### Güven Zinciri

Depo iki tür dosya sunar: paketlerin kendisi ve bir **dizin dosyası**. Dizin, her paketin
adını, sürümünü, bağımlılıklarını ve **içerik özetini** taşır. Dizin dosyası ise imzalanır.

Zincir üç halkadır:

1. Açık anahtar, depoyu yöneten tarafın kimliğini temsil eder ve sisteme bir kez tanıtılır.
2. Dizin dosyasının imzası bu anahtarla doğrulanır; imza geçerliyse dizinin içeriği
   değiştirilmemiştir.
3. İndirilen her paketin özeti, dizindeki değerle karşılaştırılır; eşleşiyorsa paket
   değiştirilmemiştir.

Tek bir imza, binlerce paketi dolaylı olarak kapsar. Paketlerin ayrı ayrı imzalanması
gerekmez; özetleri imzalı bir dosyada durduğu için yeterlidir.

Zincir küçük ölçekte kurulup doğrulanabilir. Aşağıdaki depo iki paket, bir dizin dosyası,
dizinin imzası ve deponun açık anahtarından oluşur:

```
$ ls
DIZIN  DIZIN.asc  cizim-2.0.pkg  depo-anahtari.asc  rapor-1.4.pkg
```

#### Anahtarın Tanıtılması

İlk adım anahtarı incelemektir. Anahtarın kimliği, **parmak izi** denen sabit uzunluktaki
özetiyle temsil edilir:

```
$ gpg --show-keys --with-fingerprint depo-anahtari.asc
gpg: directory '/home/ogrenci/.gnupg' created
gpg: keybox '/home/ogrenci/.gnupg/pubring.kbx' created
pub   ed25519 2026-07-26 [SC]
      E31E 9629 AEBE 63E9 0EEB  EDEE A258 E130 F14C ACAA
uid                      Depo Bakimcisi <bakim@ornek>
```

Bu noktada kritik bir adım vardır ve atlanması zincirin tamamını anlamsızlaştırır: parmak
izi, anahtarın indirildiği kanaldan **bağımsız** bir kaynakla karşılaştırılmalıdır. Anahtarı
deponun kendisinden indirip yine deponun söylediği parmak iziyle doğrulamak, hiçbir şey
doğrulamaz.

Aynı sorun dosya aktarımı dersinin şifreli kabuk bölümünde, sunucu parmak izinde de vardı
ve çözümü aynıdır: ilk karşılaşmada kimlik başka bir kanaldan teyit edilir, sonrasında
değişiklik otomatik yakalanır.

Teyitten sonra anahtar sisteme alınır:

```
$ gpg --import depo-anahtari.asc
gpg: /home/ogrenci/.gnupg/trustdb.gpg: trustdb created
gpg: key A258E130F14CACAA: public key "Depo Bakimcisi <bakim@ornek>" imported
gpg: Total number processed: 1
gpg:               imported: 1
```

#### Zincirin Doğrulanması

Dizinin imzası anahtarla sınanır:

```
$ gpg --verify DIZIN.asc DIZIN
gpg: Signature made Sun Jul 26 19:37:53 2026 UTC
gpg:                using EDDSA key E31E9629AEBE63E90EEBEDEEA258E130F14CACAA
gpg: Good signature from "Depo Bakimcisi <bakim@ornek>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: E31E 9629 AEBE 63E9 0EEB  EDEE A258 E130 F14C ACAA
```

İki satır ayrı şeyler söyler ve karıştırılmamalıdır. **"Good signature"**, dosyanın bu
anahtarla imzalandığını ve imzadan sonra değişmediğini bildirir — bu, matematiksel bir
doğrulamadır. **Uyarı** ise anahtarın sahibinin gerçekten iddia ettiği kişi olduğuna dair
bir kanıt bulunmadığını söyler; bu, yukarıdaki bağımsız kanal teyidinin yapılmadığı anlamına
gelir. İmza geçerlidir, ama kime ait olduğu ayrı bir sorudur.

Dizin doğrulandıktan sonra paketlerin özetleri sınanır:

```
$ cat DIZIN
3375dab7d8aa59a185e9e8f5e0f4095517d89bdb75245ef22a25966e2e348756  cizim-2.0.pkg
3fe6fac9c36f99b284199580aead74c6c2d33f3a60449954c90dac700ca48e08  rapor-1.4.pkg
$ sha256sum -c DIZIN
cizim-2.0.pkg: OK
rapor-1.4.pkg: OK
```

Zincir tamamlanmıştır: imza dizini, dizin paketleri garanti eder.

#### Zincir Neyi Yakalar

Paket dosyası yolda değiştirilirse özet uyuşmaz:

```
$ printf 'zararli icerik\n' > cizim-2.0.pkg
$ sha256sum -c DIZIN
cizim-2.0.pkg: FAILED
rapor-1.4.pkg: OK
sha256sum: WARNING: 1 computed checksum did NOT match
```

Saldırgan bunu aşmak için dizini de değiştirmek zorundadır. Özetler yeniden hesaplandığında
dizin kendi içinde tutarlı hâle gelir:

```
$ sha256sum *.pkg > DIZIN
$ sha256sum -c DIZIN
cizim-2.0.pkg: OK
rapor-1.4.pkg: OK
```

Ama imza artık uymaz:

```
$ gpg --verify DIZIN.asc DIZIN
gpg: Signature made Sun Jul 26 19:37:53 2026 UTC
gpg:                using EDDSA key E31E9629AEBE63E90EEBEDEEA258E130F14CACAA
gpg: BAD signature from "Depo Bakimcisi <bakim@ornek>" [unknown]
```

Zincirin gücü buradadır: dizini değiştirmek için imzalama anahtarı gerekir ve o anahtar
depoda değil, bakımcıdadır. Bu nedenle bir yansının ele geçirilmesi paketleri değiştirmeye
yetmez.

Bu, taşıma katmanındaki şifrelemenin sağlayamadığı bir güvencedir. Şifreli bir indirme,
verinin **yolda** değişmediğini gösterir; sunucudaki içeriğin doğru içerik olduğunu
göstermez. İmza ise içeriğin kaynağını doğrular ve yansılardan geçmiş olması bunu
değiştirmez. İki koruma birbirinin yerine geçmez.

#### Depo Eklemek Bir Güven Kararıdır

Sisteme yeni bir depo eklemek, o deponun bakımcısına şu yetkileri vermektir: sisteme paket
kurabilme, kurulum betiklerini kök yetkisiyle çalıştırabilme ve var olan paketleri kendi
sürümleriyle değiştirebilme.

Son madde en az fark edilenidir. Yeni depo, sistem deposundaki bir paketle aynı adı taşıyan
ve daha yüksek sürüm numaralı bir paket sunarsa, yükseltmede o paket sistemin paketinin
yerini alır. Bu nedenle paket yöneticileri **öncelik** düzeneği sunar: her depoya bir ağırlık
verilir ve aynı paketin hangi kaynaktan alınacağı bu ağırlıkla belirlenir.

Uygulamada üç ölçüt izlenir:

**Depo sayısı az tutulur.** Her ek depo, güvenilmesi gereken bir taraf ekler.

**Ek depoların kapsamı daraltılır.** Yalnızca gereken paketlerin o depodan alınması,
öncelik kuralları veya paket adı sınırlamalarıyla sağlanır.

**Anahtarlar depo başına ayrılır.** Tek bir anahtarın tüm depolar için geçerli sayılması,
bir anahtarın ele geçirilmesini tüm depoları ele geçirmeye dönüştürür.

Bir depodan yalnızca birkaç paket gerekiyorsa, deponun tamamını eklemek yerine paket
dosyalarını indirip özetleriyle doğrulamak daha dar bir güven alanı bırakır. Bunun bedeli,
güncellemelerin otomatik gelmemesidir.

#### Özet

- Depo tanımı adres, yayın, bileşen, mimari ve doğrulama anahtarından oluşur.
- Depo, paketlerin yanında paket özetlerini taşıyan bir dizin dosyası sunar ve bu dosya
  imzalanır.
- Güven zinciri üç halkadır: anahtar bakımcıyı, imza dizini, dizindeki özetler paketleri
  doğrular.
- Anahtarın parmak izi, anahtarın geldiği kanaldan bağımsız bir kaynakla teyit edilmelidir;
  aksi hâlde zincir kendi kendini doğrular.
- Geçerli imza, dosyanın değişmediğini gösterir; anahtarın sahibinin kim olduğu ayrı bir
  sorudur ve uyarı satırı bunu bildirir.
- Taşıma şifrelemesi verinin yolda değişmediğini, imza ise içeriğin kaynağını doğrular;
  ikisi birbirinin yerine geçmez.

#### Sonraki Adım

Sistem tanındı, dosyalar düzenlendi, izinler kuruldu ve yazılım kurma yolu açıldı. Geriye
tek bir eksik kalıyor: bu kursta oluşturulan betik ve yapılandırma dosyaları, terminalden
çıkmadan nasıl düzenlenir? Kursun son dersi terminal metin editörlerini — kip tabanlı ve
kipsiz tasarımları — ele alır ve hangi durumda hangisinin seçileceğini gösterir.

### Terminal Metin Editörleri

Source: https://academia.sh/tr/kurslar/linuxa-giris/terminal-metin-editorleri

Satır editöründen ekran editörüne uzanan tasarım çizgisi, kip tabanlı ve kipsiz editörlerin karşılaştırması, temel düzenleme komutları ve editör seçiminin ortam değişkeniyle bildirilmesi.

Kurs boyunca dosyalar `printf` ve yönlendirmeyle oluşturuldu. Bu, tek satırlık dosyalar için
işe yarar; bir betiğin ortasındaki satırı değiştirmek veya bir yapılandırma dosyasına iki
satır eklemek için yetersizdir.

Grafik arayüz bulunmayan bir sunucuda — uzak oturumların çoğunda durum budur — düzenleme
terminalde yapılır. Bu ders terminal editörlerinin iki tasarım ailesini ve aralarındaki
seçimi ele alır.

#### Satır Editörü

Terminal editörlerinin tasarımı, yazıcı terminallerin kullanıldığı dönemden gelir. O
dönemde ekran yoktu; çıktı kâğıda basılıyordu ve imleci hareket ettirmek diye bir şey söz
konusu değildi. Düzenleme, satır numaraları üzerinden komutlarla yapılıyordu.

Bu tasarımın temsilcisi `ed` hâlâ POSIX'te tanımlıdır ve çalışır durumdadır. Proje betiğine
bir satır eklemek için tam bir oturum:

```
$ ed betik/ozet.sh
139
$
echo "ham olcum dosyasi: $(ls -1 "$HOME/proje/veri/ham" | wc -l)"
a
echo "guncel olcum: $(readlink "$HOME/proje/veri/guncel.csv")"
.
%p
#!/bin/sh
# proje/veri/ham icindeki olcum dosyalarinin sayisini bildirir
echo "ham olcum dosyasi: $(ls -1 "$HOME/proje/veri/ham" | wc -l)"
echo "guncel olcum: $(readlink "$HOME/proje/veri/guncel.csv")"
w
202
q
```

Oturum satır satır okunmalıdır. Açılışta yazdırılan `139`, dosyanın bayt sayısıdır. `$`
komutu son satırı yazdırır. `a` ekleme kipine geçer; sonraki satırlar dosyaya eklenir ve tek
başına bir nokta ekleme kipini bitirir. `%p` dosyanın tamamını yazdırır. `w` yazar ve yeni
bayt sayısını bildirir, `q` çıkar.

`ed` istem göstermez ve hata durumunda yalnızca bir soru işareti yazdırır. Bu, gündelik
kullanım için elverişsizdir; ancak iki nedenle önemlidir. Birincisi, komut dilinin
tamamı sonraki editörlere miras kalmıştır. İkincisi, `ed` betiklerden yönlendirmeyle
sürülebilir ve bu, kurtarma ortamlarında bazen tek seçenektir.

#### Kip Tabanlı Ekran Editörü

Ekranlı terminaller yaygınlaştığında, satır editörünün üzerine bir **görsel kip** eklendi:
dosyanın bir bölümü ekranda gösterilir, imleç üzerinde gezinir. Bu tasarım POSIX'te `vi` adıyla
standartlaştırılmıştır ve standarda uyan her sistemde bulunması beklenir.

Editörün ayırt edici özelliği **kiplerdir**. Aynı tuş, bulunulan kipe göre farklı iş yapar:

| Kip | İşlevi | Nasıl girilir |
|---|---|---|
| Normal | Gezinme ve düzenleme komutları | `Esc` |
| Ekleme | Yazılan karakterler metne girer | `i`, `a`, `o` |
| Komut satırı | Satır editörü komutları | `:` |

Tasarımın gerekçesi, tuşların bir **dile** dönüşmesidir. Normal kipte harf tuşları
karakter girmediği için tümü komut olarak kullanılabilir; komutlar da eylem ve hareket
birleşimiyle kurulur. `d` silme eylemi, `w` bir sözcük ilerleme hareketidir; `dw` bir
sözcüğü siler. `3dw` üç sözcüğü siler. Öğrenilen her hareket, öğrenilen her eylemle
birleşebilir.

Karşılaştırıldığı yaklaşım, komutları değiştirici tuş bileşimlerine bağlamaktır. O
yaklaşımda komut sayısı, bileşim sayısıyla sınırlıdır ve bileşimler birleştirilemez.

Kip tabanlı tasarımın ikinci kazancı, yalnızca temel karakterleri kullanmasıdır: ok tuşları
ve değiştirici bileşimleri göndermeyen terminallerde de çalışır. Bu, uzak oturumlar ve
kurtarma konsolları için pratik bir üstünlüktür.

Bedeli, ekleme kipinde yazılan bir komutun metne karışmasıdır. Kip karışıklığı, yeni
kullanıcıların en sık karşılaştığı sorundur ve çözümü sabittir: emin olunmadığında `Esc`
tuşuna basılır, normal kipe dönülür.

#### En Küçük Hayatta Kalma Kümesi

Bir dosyayı açmak, değiştirmek ve kaydetmek için gereken komutlar azdır:

| Komut | İşlevi |
|---|---|
| `i` | İmlecin önünde ekleme kipine geçer |
| `a` | İmlecin ardında ekleme kipine geçer |
| `o` | Altına yeni satır açar ve ekleme kipine geçer |
| `Esc` | Normal kipe döner |
| `h` `j` `k` `l` | Sol, aşağı, yukarı, sağ |
| `0` / `$` | Satır başı / satır sonu |
| `gg` / `G` | Dosya başı / dosya sonu |
| `x` | İmleçteki karakteri siler |
| `dd` | Bulunulan satırı siler |
| `u` | Son değişikliği geri alır |
| `/desen` | İleri arama; `n` sonraki eşleşme |
| `:w` | Kaydeder |
| `:q` | Çıkar |
| `:q!` | Değişiklikleri atarak çıkar |
| `:wq` | Kaydeder ve çıkar |

Son dört satırdaki iki nokta üst üste ile başlayan komutlar, satır editörünün komutlarıdır.
Miras burada görünür: `:w` ve `:q`, `ed` oturumundaki `w` ve `q` ile aynı komutlardır.

Aynı komut dili doğrudan da çalıştırılabilir; editörün satır kipi betiklerden sürülebilir:

```
$ printf '%s/dosyasi/sayisi/\nwq\n' | ex -s /tmp/duzenle.sh
$ cat /tmp/duzenle.sh
#!/bin/sh
# proje/veri/ham icindeki olcum dosyalarinin sayisini bildirir
echo "ham olcum sayisi: $(ls -1 "$HOME/proje/veri/ham" | wc -l)"
echo "guncel olcum: $(readlink "$HOME/proje/veri/guncel.csv")"
```

`%s/eski/yeni/` komutu tüm satırlarda değiştirme yapar; `wq` kaydedip çıkar. Ekran
editöründe iki nokta üst üste yazıp aynı komutu vermek aynı sonucu üretir. Ekran tabanlı bir
oturum metin olarak gösterilemez, ama komut dili gösterilebilir ve gösterilen budur.

#### Kipsiz Editörler

İkinci tasarım ailesi kip kullanmaz: yazılan karakterler doğrudan metne girer, komutlar
denetim tuşu bileşimleriyle verilir ve kullanılabilir komutlar ekranın altında sürekli
listelenir.

Karşılaştırma iki eksende yapılır:

| Ölçüt | Kip tabanlı | Kipsiz |
|---|---|---|
| Öğrenme eşiği | Yüksek; kip kavramı öğrenilmeli | Düşük; komutlar ekranda yazılı |
| Komut birleştirme | Eylem ve hareket birleşir | Bileşim başına tek komut |
| Bulunma güvencesi | POSIX'te tanımlı, her sistemde beklenir | Ayrı paket, kurulu olmayabilir |
| Sınırlı terminal | Temel karakterlerle çalışır | Denetim bileşimleri gerekir |

Üçüncü satır pratikte belirleyicidir. Yalın bir sistemde veya bir kurtarma ortamında kipsiz
editör bulunmayabilir:

```
$ command -v vi ed nano
/usr/bin/vi
/usr/bin/ed
/usr/bin/nano
```

Bu sistemde üçü de vardır; ancak yalnızca ilk ikisinin bulunacağı varsayılabilir. Bu nedenle
kip tabanlı editörün hayatta kalma kümesi, tercih edilen editör ne olursa olsun
öğrenilmelidir.

#### Editör Tercihini Bildirmek

Birçok program, düzenleme gerektiğinde bir editör başlatır: zamanlanmış görev tanımları,
sürüm denetimi araçlarının ileti ekranları ve yetkili dosya düzenleme araçları. Hangi
editörün açılacağı ortam değişkenlerinden okunur.

```
$ echo "EDITOR=${EDITOR:-tanimsiz}"
EDITOR=tanimsiz
$ EDITOR=vi
$ export EDITOR
$ echo "EDITOR=$EDITOR"
EDITOR=vi
```

`export` olmadan yapılan atama yalnızca kabuğun kendi değişkeni olur ve çalıştırılan
programlara aktarılmazdı; komut yolu dersindeki ortam ayrımı burada doğrudan uygulanır.
Ayarın kalıcı olması için, `PATH` değişikliğiyle aynı yere — oturum açılışında okunan
yapılandırma dosyasına — yazılır.

İki değişken kullanılır: tam ekran editörü için `VISUAL`, satır tabanlı ortamlar için
`EDITOR`. İkisi de tanımlıysa programların çoğu `VISUAL` değerini yeğler; yalnızca biri
tanımlanacaksa `EDITOR` yeterlidir.

#### Özet

- Terminal editörlerinin komut dili, ekransız terminaller için tasarlanan satır
  editöründen miras alınmıştır ve `:` ile başlayan komutlarda hâlâ görünür.
- Kip tabanlı editörde harf tuşları komut olarak kullanılabildiği için eylem ve hareket
  birleşerek bir komut dili oluşturur.
- Bir dosyayı açıp değiştirip kaydetmek için gereken komut kümesi küçüktür ve emin
  olunmadığında `Esc` normal kipe döndürür.
- Kipsiz editörlerin öğrenme eşiği düşüktür ama her sistemde bulunacakları varsayılamaz.
- Editör tercihi `VISUAL` ve `EDITOR` ortam değişkenleriyle bildirilir ve `export`
  edilmedikçe çalıştırılan programlara aktarılmaz.

#### Kurs Kapanışı

Kurs, tek bir dizin ağacı üzerinde ilerledi. Ağaç kurulduğunda boştu; kapanışta üzerinde
yapılmış her işlemi taşıyor:

```
$ betik/ozet.sh
ham olcum dosyasi: 4
guncel olcum: ham/olcum-03.csv
```

Bu iki satırın arkasında kursun tamamı vardır. Betiğin çalışması için çalıştırma bitinin
açık olması gerekti; yol eğik çizgi içerdiği için kabuk arama listesine hiç bakmadı.
Saydığı dosyalar oluşturuldu, kopyalandı ve taşındı; sayıldıkları dizin yol çözümlemesiyle
bulundu. Bildirdiği güncel ölçüm bir sembolik bağın hedefidir. Ağacın tamamı arşivlendi,
sıkıştırıldı, uzak bir makineye eşitlendi; bir gruba açıldı ve paylaşılan dizini özel izin
bitleriyle korundu.

Kursun kazanımları geriye dönük olarak şöyle toplanır:

- **Gezinme ve dosya işlemleri:** Hiyerarşinin mantığı, yol çözümlemesi, oluşturma,
  kopyalama, taşıma, silme, bağlar, arşivleme ve aktarım.
- **İzinler ve sahiplik:** Kimliğin sayısal temsili, dokuz izin biti ve sekizlik gösterim,
  sahiplik değişikliği, yetki yükseltme ve üç özel bit.
- **Paket yönetimi:** Paketin yapısı, bağımlılık çözümlemesi, işlem sınıfları ve depo
  güven zinciri.

Kurs boyunca komutların yanında bir alışkanlık kümesi de kuruldu ve bunlar komutlardan daha
uzun ömürlüdür: yıkıcı bir komutu çalıştırmadan önce açılımını görmek, bir arşivi açmadan
önce listelemek, bir eşitlemeyi kuru çalışmayla denemek, bir aktarımı özetiyle doğrulamak ve
bir yetkiyi olabilecek en dar kapsamda almak.

Bir sonraki kurs, bu kursun bilinçli olarak dışarıda bıraktığı katmanı ele alır: komutları
birbirine bağlamak. Kabuk Programlama kursu girdi ve çıktı yönlendirmesini, boru hatlarını,
değişkenleri, koşulları ve döngüleri kurar; bu kursta tek tek çalıştırılan komutlar orada
yeniden çalıştırılabilir betiklere dönüşür. Kabuk dersinde tanıtılan sözcüklere bölme ve
açılım kuralları, o kursun dilbilgisinin temelini oluşturacaktır.

