Rehber

Yeni başlayanlar için bash script: ilk betik, değişkenler, koşullar, döngüler ve cron

Güncellendi: · Skillaria.Top

Bash script, #!/bin/bash satırıyla başlayan, chmod +x ile çalıştırma izni alan ve ./script.sh biçiminde çalıştırılan, kabuk komutlarından oluşan düz bir metin dosyasıdır. Betiklerde değişkenler, $1 ve $2 argümanları, if koşulları, for ve while döngüleri kullanılır; düzenli zamanlama ise crontab -e ile ayarlanır.

Bash script, terminalde tek tek yazacağınız komutların yer aldığı düz bir metin dosyasıdır. Betik, #!/bin/bash shebang satırıyla başlar, chmod +x ile çalıştırma iznini alır ve ./script.sh olarak çalıştırılır. Bu rehber, yeni başlayanlar için bash script'i ilk satırdan zamanlanmış çalıştırmaya kadar anlatır: değişkenler, argümanlar, koşullar, döngüler, hata yönetimi ve cron.

Bir dakikada ilk bash script'iniz

Herhangi bir editörde dosya oluşturun, örneğin nano ile:

nano hello.sh
#!/bin/bash
# İlk betik: karşılama ve sistem hakkında biraz bilgi
echo "Merhaba, $USER!"
echo "Bugün: $(date +%Y-%m-%d)"
echo "Şu anda buradasınız: $(pwd)"

Kaydedin (Ctrl+O, Enter, Ctrl+X), çalıştırma izni verin ve çalıştırın:

$ chmod +x hello.sh
$ ./hello.sh
Merhaba, alice!
Bugün: 2026-10-12
Şu anda buradasınız: /home/alice

# ile başlayan satırlar yorumdur. $(komut), komutun çıktısını doğrudan satıra yerleştirir.

Shebang: ilk satır neden önemli

#!/bin/bash satırı, sisteme dosyayı hangi yorumlayıcıyla çalıştıracağını söyler. Bu satır olmadan betik, o an hangi kabuk bulunursa onunla çalışır. Bazı sistemlerde /bin/sh bash değil, daha sade olan dashtır ve bazı yapılar orada çalışmaz.

Sık görülen bir başka biçim #!/usr/bin/env bash'tır: bash'i PATH içinde arar; bash /bin içinde değilse kullanışlıdır.

Betik nasıl çalıştırılır ve neden ./

İki yol vardır:

  • ./hello.sh — shebang ve x izni gerekir. ./ öneki zorunludur, çünkü geçerli dizin PATH'te yer almaz.
  • bash hello.sh — çalıştırma izni gerekmez, yorumlayıcı açıkça belirtilmiştir.

Eğer ./ olmadan command not found, chmod +x olmadan Permission denied görüyorsanız, nedenler tam olarak bunlardır. Kendi betiklerinizi her yerden adıyla çağırmak için ~/bin veya /usr/local/bin dizinine koyun.

Değişkenler

Değişken, = işaretinin etrafında boşluk olmadan tanımlanır ve $ ile okunur:

#!/bin/bash
name="backup"
dir="/var/backups"
today=$(date +%F)

echo "Dosya: ${dir}/${name}-${today}.tar.gz"

Süslü parantezler değişken adını çevresindeki metinden ayırır. Boşluklu name = "backup" satırı hatalıdır: bash name adında bir komut çalıştırmaya çalışır.

Tırnak işaretleri önemlidir

Çift tırnak içinde değişkenler yerine konur, tek tırnak içinde konmaz. Değişkenleri neredeyse her zaman çift tırnak içine alın; aksi halde boşluk içeren bir dosya adı iki argümana bölünür.

file="rapor notu.txt"
rm $file      # hata: «rapor» ve «notu.txt» adlı dosyaları silmeye çalışır
rm "$file"    # doğru
echo '$HOME'  # olduğu gibi $HOME yazar
echo "$HOME"  # /home/alice yazar

Ortam değişkenleri

$HOME, $USER, $PATH gibi değişkenleri sistem tanımlar. Kendi değişkeninizi export ile alt süreçlere aktarabilirsiniz. Kalıcı ayarlar ~/.bashrc veya ~/.profile dosyasına yazılır.

Betik argümanları

Çalıştırırken verilen değerlere $1, $2 vb. ile erişilir.

ead>
Değişkenİçeriği
$0betiğin adı
$1, $2…birinci, ikinci argüman
$#argüman sayısı
"$@"tüm argümanlar ayrı ayrı
$?son komutun çıkış kodu
$$çalışan betiğin PID'si
#!/bin/bash
echo "Betik $0, $# argüman aldı"
echo "Birinci: $1"
$ ./args.sh nginx 80
Betik ./args.sh, 2 argüman aldı
Birinci: nginx

Kullanıcıdan girdi almak için read komutu kullanılır: read -p "Adınızı girin: " name.

if koşulları

Her komut bir çıkış kodu döndürür: 0 başarı, diğer her değer hata demektir. if yapısı tam olarak bu kodu denetler. Karşılaştırmalar için [[ ... ]] kullanılır ve parantezlerin içindeki boşluklar zorunludur.

#!/bin/bash
if [[ $# -eq 0 ]]; then
    echo "Kullanım: $0 <dizin>"
    exit 1
fi

if [[ -d "$1" ]]; then
    echo "Dizin $1 mevcut"
elif [[ -f "$1" ]]; then
    echo "$1 bir dosya, dizin değil"
else
    echo "$1 bulunamadı"
fi
ead>
DenetimAnlamı
-f filenormal dosya var
-d dirdizin var
-e pathyol var
-x filedosya çalıştırılabilir
-z "$var" / -n "$var"metin boş / boş değil
"$a" == "$b", !=metin karşılaştırması
-eq -ne -lt -le -gt -gesayı karşılaştırması

Doğrudan herhangi bir komutu da koşul olarak denetleyebilirsiniz:

if systemctl is-active --quiet nginx; then
    echo "nginx çalışıyor"
else
    echo "nginx durmuş"
fi

Birçok seçenek için case kullanışlıdır:

case "$1" in
    start)   echo "Başlatılıyor" ;;
    stop)    echo "Durduruluyor" ;;
    *)       echo "Bilinmeyen komut: $1"; exit 1 ;;
esac

for ve while döngüleri

for: bir listeyi dolaşmak

for host in web1 web2 db1; do
    echo "$host kontrol ediliyor"
    ping -c 1 -W 1 "$host" > /dev/null && echo "  erişilebilir" || echo "  erişilemiyor"
done

for file in /var/log/*.log; do
    echo "$file: $(wc -l < "$file") satır"
done

for i in {1..5}; do
    echo "Deneme $i"
done

while: koşul doğru olduğu sürece

Bir dosyayı satır satır okumanın klasik örneği:

while read -r user; do
    echo "Kullanıcı: $user"
done < users.txt

Ve bir servisin ayağa kalkmasını beklemek:

count=0
until curl -sf http://localhost:8080/health > /dev/null; do
    count=$((count + 1))
    if [[ $count -ge 10 ]]; then
        echo "Servis ayağa kalkmadı"
        exit 1
    fi
    sleep 3
done
echo "Servis hazır"

Bash'te aritmetik çift parantezle yazılır: $((a + b)). Yalnızca tam sayılarla çalışır.

Fonksiyonlar

Tekrarlanan kodlar fonksiyonlara taşınır. Fonksiyon içindeki argümanlar yine $1, $2'dir ve local değişkenin dışarı sızmasını engeller.

log() {
    local level="$1"; shift
    echo "$(date '+%F %T') [$level] $*"
}

log INFO "Yedekleme başlıyor"
log ERROR "Diskte yer kalmadı"

Hataları yönetmek: set -euo pipefail

Varsayılan olarak bash, başarısız bir komuttan sonra da çalışmaya devam eder; yedekleme betiği hiçbir şey kopyalamadan «başarıyla» bitebilir. Bu yüzden betiklerin başına sıkı mod eklenir:

#!/bin/bash
set -euo pipefail
  • -e — ilk hatada dur.
  • -u — tanımlanmamış bir değişkene başvuruyu hata say (boş bir DIR ile rm -rf "$DIR/" yazılmasını engeller).
  • -o pipefail — bir borunun herhangi bir parçası başarısız olursa, tüm boru başarısız sayılır.

Hata ayıklamak için betiği bash -x script.sh ile çalıştırın: bash her komutu çalıştırmadan önce yazdırır. Çalıştırmadan önce tipik hataları bulmak için shellcheck aracı yardımcı olur.

Uygulamalı örnek: yedekleme betiği

#!/bin/bash
set -euo pipefail

SRC="${1:-/var/www}"
DST="/var/backups/site"
KEEP_DAYS=7
STAMP=$(date +%F_%H-%M)

mkdir -p "$DST"
tar -czf "$DST/site-$STAMP.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "Arşiv oluşturuldu: $DST/site-$STAMP.tar.gz"

# KEEP_DAYS günden eski arşivleri sil
find "$DST" -name "site-*.tar.gz" -mtime +"$KEEP_DAYS" -delete

${1:-/var/www} ifadesi şu anlama gelir: «birinci argüman; yoksa /var/www». Betiği /usr/local/bin/backup-site.sh olarak kaydedin ve çalıştırılabilir yapın: sudo chmod +x /usr/local/bin/backup-site.sh.

Zamanlanmış çalıştırma: cron

Cron, komutları belirli zamanlarda çalıştıran servistir. Kullanıcının görevleri crontab -e ile düzenlenir, crontab -l ile listelenir; root'un görevleri için sudo crontab -e kullanılır.

Bir cron satırı beş zaman alanı ve ardından komuttan oluşur:

# dakika saat gün_ayın ay haftanın_günü komut
30 2 * * * /usr/local/bin/backup-site.sh >> /var/log/backup.log 2>&1
ead>
ZamanlamaNe zaman çalışır
*/5 * * * *her 5 dakikada bir
0 * * * *her saatin başında
30 2 * * *her gün 02:30'da
0 9 * * 1-5hafta içi 09:00'da
0 3 1 * *her ayın 1'inde 03:00'te
@rebootaçılıştan sonra bir kez

Betik elle çalışıyor, cron'da neden çalışmıyor

  • Farklı ortam. Cron görevleri minimal bir PATH ile ve ~/.bashrc olmadan çalıştırır. Komutların ve dosyaların tam yollarını yazın veya crontab'ın başında PATH tanımlayın.
  • Farklı geçerli dizin. Görev ev dizininden başlar, betiğin bulunduğu dizinden değil. Mutlak yollar kullanın.
  • % işareti. crontab'ta % yeni satır anlamına gelir; bu yüzden görev satırındaki date +%F ifadesinin \% olarak kaçırılması gerekir. Daha kolayı, komutu betiğe koymaktır.
  • Çıktı kaybolur. Çıktıyı bir günlük dosyasına yönlendirin (>> file 2>&1), yoksa hatayı göremezsiniz. Cron çalışmaları journalctl -u cron ile görünür (RHEL türevlerinde servis adı crond'dur).

systemd olan sistemlerde cron'a alternatif olarak systemd zamanlayıcıları vardır: çıktılarını günlüğe yazarlar ve kaçırılan çalışmaları telafi edebilirler.

Sonuç

Yeni başlayanlar için bash script, #!/bin/bash shebang satırıyla başlayan, çalıştırma iznine sahip ve komutların sırasını içeren bir dosyadır. Tırnaklı değişkenleri, if ile argüman denetimini, for ve while döngülerini ve set -euo pipefail sıkı modunu ekleyin; cron'un zamanında çalıştıracağı güvenilir bir otomasyon aracı elde edersiniz. Bash betikleri, ortam ve cron, kurs içinde uygulamalı olarak işlenmektedir.

Sık sorulan sorular

bash ile sh arasındaki fark nedir?

sh standart bir POSIX kabuğudur; bash ise dizi, çift parantez ve başka kolaylıklar içeren genişletilmiş sürümüdür. Bash yapıları içeren betiği sh ile değil, bash ile çalıştırın.

Bash betiğinin uzantısı ne olmalı?

Linux uzantıya bakmaz; yorumlayıcıyı shebang belirler. <code>.sh</code> yalnızca bir gelenektir ve dosyanın betik olduğunu insanlara gösterir.

Betiğe parolayı güvenli biçimde nasıl veririm?

Argüman olarak vermeyin, çünkü argümanlar <code>ps</code> ile diğer kullanıcılar tarafından görülebilir. 600 izinli bir dosyadaki ortam değişkenini kullanın ya da <code>read -s</code> ile ekrana yansımadan girdi alın.

Betiğin root olarak çalışıp çalışmadığını nasıl anlarım?

Kullanıcı kimliğini sıfırla karşılaştırın: <code>if [[ $EUID -ne 0 ]]; then echo "root gerekli"; exit 1; fi</code>.

SSH'den çıktıktan sonra da çalışması için betiği nasıl başlatırım?

<code>nohup ./script.sh &</code> kullanın ya da bir tmux veya screen oturumunda çalıştırın. Kalıcı çalışma için betiği bir systemd servisine dönüştürün.

Bu konuyu videoyla öğrenin

Bu konu “Linux: с нуля до уверенного администрирования” kursunda uygulamalı olarak ayrıntılı işleniyor.

Kursa git