Giriş ve Temeller

Bash Script (veya Bash betiği), Linux ve Unix sistemlerinde kullanılan Bash (Bourne Again SHell) kabuğu için yazılmış, içinde komutlar barındıran bir metin dosyasıdır. Bu komutlar sırasıyla çalıştırılır ve otomasyon, sistem yönetimi, dosya işlemleri gibi görevlerde sıkça kullanılır.

Bash Script Nedir?

  • Bash script, terminalde tek tek yazmak yerine bir dizi komutu bir dosyaya yazarak otomatik çalıştırmamıza olanak sağlar.
  • Genellikle .sh uzantısıyla kaydedilir (örnek: backup.sh).
  • İlk satırı genellikle shebang denilen bir ifade ile başlar:
#!/bin/bash

Bu satır, script’in Bash kabuğunda çalıştırılacağını belirtir.

Nerelerde Kullanılır?

  • Sistem bakım işleri
  • Sunucu yönetimi
  • Uygulama dağıtımı
  • Veri işleme
  • Otomatik rapor üretimi

Bash Script’in Temel Özellikleri:

  • Otomasyon sağlar: Tekrar eden görevleri otomatikleştirmek için idealdir (örneğin, yedekleme, sistem kontrolü, log temizleme).
  • Değişkenler, koşullar, döngüler, fonksiyonlar gibi programlama yapıları desteklenir.
  • Bash komutlarının yanı sıra sistem komutları (ls, cd, cp, rm, vs.) da çalıştırılabilir.

Basit Bir Bash Script Örneği:

#!/bin/bash
echo "Merhaba Arkadaşlar"

Script Dosyasını Çalıştırılabilir Yapma:

chmod +x dosya_ismi.sh
# Çalıştırmak için:
bash dosya_ismi.sh
# ya da
./dosya_ismi.sh

Scripti /usr/bin Dizinine Atma: Oluşturulan dosyayı /usr/bin içerisine taşırsanız, her dizinden çalıştırabilirsiniz.

Temel Kavramlar

Değişkenler (Variables)

  1. System Variables: Sistem tarafından tanımlanmış değişkenler.
  2. User Variables: Kullanıcı tarafından tanımlanan değişkenler.
  • Yerel ve Ortam Değişkenleri Yerel: Geçerli kabukta geçerlidir. Ortam: Alt süreçlere aktarılır. Örnek:

    VARIABLE="yerel_deger"
    export ENV_VAR="dışa_aktarilan_deger"
    
  • Parametre Genişletme Değişken değerlerini çalışma zamanında özelleştirir:

    ${VAR:-varsayilan}   # VAR tanımlı değilse 'varsayilan' kullanılır
    ${VAR:=varsayilan}   # VAR tanımlı değilse 'varsayilan' atanır
    ${VAR:+alternatif}   # VAR tanımlıysa 'alternatif' kullanılır
    ${VAR:offset:uzunluk}  # Alt dize çıkarımı
    

read Kullanımı

echo "İsminiz: "
read isim
echo "İsmim $isim"

echo "İsimler: "
read isim1 isim2 isim3
echo "İsimler: $isim1, $isim2, $isim3"

Prompt ve Gizli Giriş

read -p 'İsminiz: ' isim
read -sp 'Şifreniz: ' sifre
echo
echo "İsmim $isim"
echo "Şifrem $sifre"

Script Argümanları (ARGS) Kullanımı

#!/bin/bash

echo $0 $1 $2 $3 $4
echo $*
echo $#

dizi=("$@")
echo ${dizi[0]} ${dizi[3]}

Kontrol Yapıları

if Kullanımı

#!/bin/bash

if [Koşul]
then
  durum
fi

Koşul Türleri (Integer / String)

Integer Karşılaştırma:

  • -eq : Eşit (if [ "$a" -eq "$b" ])
  • -ne : Eşit değil
  • -gt : Büyük
  • -ge : Büyük veya eşit
  • -lt : Küçük
  • -le : Küçük veya eşit

String Karşılaştırma:

  • = : Eşit
  • ==: Eşit
  • !=: Eşit değil
  • < : Küçük (alfabetik sıralamaya göre)
  • > : Büyük (alfabetik sıralamaya göre)

AND ve OR Operatörleri

  • AND: && veya -a
  • OR : || veya -o

Örnek:

#!/bin/bash

yas=32

if [ "$yas" -gt 18 ] && [ "$yas" -lt 30 ]
then
  echo "Geçerli yaş"
else
  echo "Geçersiz yaş"
fi

Dosya Doğrulama Operatörleri

  • -e: Dosya mevcut mu?
  • -f: Dosya mevcut ve regular file mı?
  • -s: Dosya içeriği dolu mu?
  • -d: Klasör mü?
  • -r: Okunabilir mi?
  • -w: Yazılabilir mi?
  • -x: Çalıştırılabilir mi?

Örnek:

#!/bin/bash

echo -e "Dosyanın ismini giriniz:\c"
read dosyaismi

if [ -e $dosyaismi ]
then
  echo "$dosyaismi bulundu"
else
  echo "$dosyaismi bulunamadı"
fi

Case Kullanımı

#!/bin/bash

arac=$1

case $arac in
  "araba" )
    echo "$arac 2000TL'ye günlük kiralanır";;
  "Motorsiklet" )
    echo "$arac 1000TL'ye günlük kiralanır";;
  "Bisiklet" )
    echo "$arac 50TL'ye kiralanır";;
  * )
    echo "$arac yoktur";;
esac

Case Statement ile Seçim

Arac Seçimi Örneği:

#! /bin/bash

echo -e "Bir arac giriniz:\c"

read arac

case $arac in
   "araba" )
   echo "$arac 2000TL'ye günlük kiralanır";;
   "Motorsiklet" )
   echo "$arac 1000TL'ye günlük kiralanır";;
   "Bisiklet" )
   echo "$arac 50TL'ye kiralanır";;
   * )
   echo "$arac yoktur";;
esac

Karakter Seçimi Örneği:

#! /bin/bash

echo -e "Bir Karakter Giriniz:\c"

read deger

case $deger in
   [a-z] )
   echo "Kullanıcı $deger girişi yaptı a-z arasında";;
   [0-9] )
   echo "Kullanıcı $deger girişi yaptı 0-9 arasında";;
   ? )
   echo "Kullanıcı $deger girişi yaptı özel karakter";;
   * )
   echo "Kullanıcı $deger girişi yaptı bilinmeyen";;
esac

Döngüler

While Döngüsü

#! /bin/bash

i=1

while (( $i <= 2 ))
do
   echo $i
   ((i++))
   sleep 1
   gnome-terminal
done

For Döngüsü

Basit For Döngüsü

#! /bin/bash

for (( i=0; i<=5; i++ ))
do
 echo $i
done

Komutlarla For Döngüsü

#! /bin/bash

for i in ls pwd
do
 echo "----------$i-----------"
 $i
 echo
done

Range ile For Döngüsü

#! /bin/bash

for i in {1..10}
do
 echo $i
done

Aralıklı For Döngüsü

#! /bin/bash

for i in {1..10..2}
do
 echo $i
done

Until Döngüsü

#! /bin/bash

i=1

until (( $i >= 10 ))
do
 echo $i
 ((i++))
done

Break ve Continue Kullanımı

Break ile Döngüden Çıkmak

#! /bin/bash

for ((i=0; i<=10; i++))
do
   if [ $i -gt 5 ]
   then
   break
   fi
   echo "$i"
done

Continue ile Döngüyü Atlamak

#! /bin/bash

for ((i=0; i<=10; i++))
do
   if [ $i -eq 2 -o $i -eq 6 ]
   then
   continue
   fi
   echo "$i"
done

Select Yapısı

Select Kullanımı

#! /bin/bash
select isim in Mehmet Ahmet Veli Ayşe
do
 case $isim in
 Mehmet )
       echo "Mehmet seçildi";;
 Ahmet )
       echo "Ahmet seçildi";;
 Veli )
       echo "Veli seçildi";;
 Ayşe )
       echo "Ayşe seçildi";;
 * )
       echo "1 ile 4 arasında değer giriniz";;
 esac                            
done

Fonksiyonlar

Basit Fonksiyon

#! /bin/bash

function Merhaba(){
   echo "Merhaba Dostlar"
}

Merhaba

Fonksiyonlar ile Çıkış Kullanımı

#! /bin/bash

function Merhaba(){
   echo "Merhaba Dostlar"
}

cikis(){
   exit
}

Merhaba
cikis

echo "test"

Fonksiyonlar ve Değer Gönderme

#! /bin/bash

function Merhaba(){
   echo "Merhaba Dostlar"
}

cikis(){
   exit
}

Merhaba
echo "test"
cikis

Fonksiyonla Parametre Alma

#! /bin/bash

echo -e "Bir sayi giriniz:\c"
read sayi

function Karesiyap(){
   echo "Sayının karesi: $((sayi*sayi))"
}

Karesiyap

Birden Fazla Parametre Kullanma

#! /bin/bash

function cikti(){
   echo $1 $2 $3
}

cikti Ahmet evde değil

Local Değişken Kullanımı

#! /bin/bash

function cikti(){
   local isim=$1
   echo "İsmim $isim"
}

isim="Mehmet"

echo "İsmim $isim"

cikti Ahmet

echo "İsmim $isim"

Diziler

#! /bin/bash

OS=( 'Linux' 'Windows' 'Unix' )

# Tüm dizi elemanlarını gösterir
echo "${OS[@]}"

# 2. elemanı gösterir (indeks 2'dir)
echo "${OS[2]}"

# Tüm dizinin indeks sırasını gösterir
echo "${!OS[@]}"

# Dizi eleman sayısını gösterir
echo "${#OS[@]}"

# Yeni bir eleman ekleyebiliriz
OS[3]='Mac'

# Güncel diziyi gösterir
echo "${OS[@]}"

# Dizinin 1. elemanını kaldırır
unset OS[1]

# Güncel diziyi tekrar gösterir
echo "${OS[@]}"

# Dizinin indekslerini gösterir
echo "${!OS[@]}"

Bash’in Derinliklerine Giriş

Aritmetik İşlemler

#!/bin/bash

sayi1=25
sayi2=5

echo $(( sayi1 + sayi2 ))
echo $(( sayi1 - sayi2 ))
echo $(( sayi1 * sayi2 ))
echo $(( sayi1 / sayi2 ))
echo $(( sayi1 % sayi2 ))

echo $(expr $sayi1 + $sayi2)

Float Sayılar

#!/bin/bash

sayi1=20.5
sayi2=5

echo "scale=2; $sayi1 / $sayi2" | bc
echo "scale=10; sqrt($sayi2)" | bc -l

Shell'de Kullanılan Tırnaklar

  • Ters Tırnak (backticks): `komut`
    Komutları çalıştırmak için kullanılır. Komut çıktısı alınır.

  • Düz Tek Tırnak: 'ifade'
    İçeriği olduğu gibi kullanır, özel karakterleri etkilemez.

  • Düz Çift Tırnak: "ifade"
    İçeriği genişletir (değişkenler ve komutlar çalıştırılır).

Yönlendirme (Redirection)

Bash'de yönlendirme ile, giriş ve çıkış akışlarını kontrol edebiliriz.

3 İletişim Kanalı:

  1. INPUT (0): Klavye
  2. OUTPUT (1): Ekran (Standart çıktı)
  3. OUTPUT (2): Ekran (Standart hata - hata mesajları)

Yönlendirme Komutları:

  • komut > dosya
    Komutun çıktısı dosyaya yazılır.

  • komut >> dosya
    Komutun çıktısı dosyanın sonuna eklenir.

  • komut < dosya
    Komutun girdisi dosyadan okunur.

  • komut >| dosya
    Noclobber set edilmiş olsa dahi komut çıktısı dosyaya yazılır.

  • komut 2> dosya
    Komutun hataları dosyaya yazılır.

  • komut > dosya 2>&1
    Komutun çıktısı ve hataları aynı dosyaya yazılır.

  • komut &> dosya
    Komutun çıktısı ve hataları aynı dosyaya yazılır.

  • komut &>> dosya
    Komutun çıktısı ve hataları aynı dosyanın sonuna eklenir.

  • komut > dosya1 2> dosya2
    Komutun çıktısı dosya1'e, hataları dosya2'ye yazılır.

Kurallı İfadeler (Regex)

Kurallı ifadeler, metin arama ve işleme işlemlerinde kullanılan güçlü bir araçtır.

Temel Kurallı İfade Simboleri:

  • ^ : Satır başı anlamına gelir.
  • $ : Satır sonu anlamına gelir.
  • . : Herhangi bir karakteri temsil eder.
  • * : Kendisinden önceki karakteri tekrarlatır (0 veya daha fazla kez).
  • [] : Köşeli parantez içerisindeki karakterlerden biri gelebilir.
  • [^] : Köşeli parantez içerisindeki karakter haricindeki bir karakter gelebilir.
  • grep, sed, ve awk ile desen eşleme ve işleme:

    grep -E 'desen' dosya
    sed -E 's/(desen)/degistirme/g' dosya
    awk '/desen/ { print $0 }' dosya
    

Gelişmiş Özellikler

Hata Ayıklama (Debugging)

  • -x Seçeneği: Betiği bash -x betik.sh komutuyla çalıştırarak veya betiğin ilk satırına #! /bin/bash -x ekleyerek her komutun yürütülmeden önce nasıl çalıştığını görebilirsiniz.

  • set -x / set +x: Betiğin belirli bir bölümünü izlemek için set -x ile hata ayıklamayı başlatıp, set +x ile kapatabilirsiniz.

    echo "Bu kısım izlenmez."
    set -x # İzleme başlar
    sayi=0
    while ((sayi<2)); do
       echo "Sayı: $sayi"
       ((sayi++))
    done
    set +x # İzleme biter
    echo "Bu kısım da izlenmez."
    

Hata Yönetimi

  • set Komut Seçenekleri:

    • set -e: Herhangi bir komut hata verirse betiği hemen durdurur.
    • set -u: Tanımlanmamış değişken kullanıldığında hata verir. Bu, yazım hatalarını yakalamanıza yardımcı olur.
  • Çıkış Kodları ($?): Her komutun ardından $? değişkeni, komutun başarıyla tamamlanıp tamamlanmadığını (0: başarılı, diğerleri: hata) gösteren bir kod içerir.

    komut
    if [[ $? -ne 0 ]]; then
        echo "Hata: 'komut' başarısız oldu."
        exit 1
    fi
    
  • Hataları Yakalama (trap): trap 'yapılacak_iş' ERR kullanarak bir hata (eğer set -e açıksa) oluştuğunda belirli bir komutu çalıştırabilirsiniz. $LINENO o anki satır numarasını verir.

    trap 'echo "Hata $LINENO. satırda oluştu!"' ERR
    set -e
    ls /olmayan/dizin # Bu bir hataya neden olur
    echo "Bu asla çalışmaz."
    

Süreç Yönetimi

  • Arka Plan ve Ön Plan

    komut &        # Arka planda çalıştır
    fg             # Görevi ön plana al
    jobs           # Arka plan görevlerini listele
    
  • Alt Kabuklar

    (komut1; komut2)  # Komutları alt kabukta çalıştır
    

Komut İkamesi

sonuc=$(komut)
echo "Sonuç: $sonuc"

Yaygın Kullanım Senaryoları

Otomasyon

  • Örnek: Yedekleme Betiği

    #!/bin/bash
    KAYNAK_DIZIN="/kaynak/yolu"
    HEDEF_DIZIN="/yedek/yolu"
    tar -czf "$HEDEF_DIZIN/yedek_$(date +%Y%m%d).tar.gz" "$KAYNAK_DIZIN"
    

Günlük (Log) Ayrıştırma

grep "ERROR" gunluk.txt | awk '{print $1, $2}'

Sistem İzleme

while true; do
    echo "$(date): $(uptime)" >> sistem.log
    sleep 60
done

En İyi Uygulamalar

  • Kodunuzu Yorumlayın: Bakımı kolay betikler yazın.

  • Hata Yönetimi: Hataları öngörün ve yönetin.

  • Shellcheck Kullanın: Betiklerinizi analiz edin.

    shellcheck betik.sh
    
  • Mutlak Yollar Kullanın: $PATH bağımlılığından kaçının.

  • Güvenli Ortamda Test Edin: Betikleri doğrudan üretim sisteminde çalıştırmayın.

Klavye Kısayolları

İşinize yarıyacak bazı popüler terminal kısayolları:

  • Ctrl + R: Komut geçmişinizde arama yapar
  • Ctrl + E: İmleci en başa götürür
  • Ctrl + A: İmleci en sona götürür
  • Ctrl + U: İmlecin solundaki kısmı siler
  • Ctrl + K: İmlecin sağındaki kısmı siler
  • Ctrl + P: Komut geçmişinizde geri gider
  • Ctrl + L: Terminal ekranınızı temizler
  • Ctrl + D: Eğer aktif bir process'in içerisinde iseniz onu kapatır, değilseniz ve terminal'de herhangi bir şey yazılıysa imleçten sonraki karakteri siler, eğer hiçbişe yazılı değilse kullanıcıdan veya bulunduğun terminal'den çıkış yapar

Bazı İpuçlar:

  • $$ geçerli (şu anki) işlemin PID'sidir (Process ID - İşlem Kimliği).
  • $! arka planda (background) çalıştırılan son işlemin PID'sini verir.
  • $? son çalıştırılan komutun dönüş (çıkış) kodudur.
  • $# $* içindeki argümanların sayısını verir.
  • $* geçerli işleme (komut dosyasına) iletilen tüm argümanların listesidir.
  • $@ komut dosyasına iletilen tüm argümanların boşlukla ayrılmış halini tutar.
  • !! son çalıştırılan komutu tekrar çalıştırır.

Öğrenim Kaynakları

Project Ideas:

Cheet Sheet: https://devhints.io/bash

Tutorial with examples: https://linuxhint.com/3hr_bash_tutorial/