kill ve killall Komutu ile Linux’ta Süreç Sonlandırma Teknikleri

Bir sistemi yönetirken en can sıkıcı anlardan biri, bir sürecin kontrolden çıkması ve sistemi yavaşlatmasıdır. Bellek sızıntısı yapan bir uygulama, kilitlenmiş bir servis ya da zombie haline gelmiş bir process… Bunlarla başa çıkmanın en doğrudan yolu kill ve killall komutlarını iyi bilmektir. Bu yazıda bu iki komutu, sinyal mekanizmasını ve gerçek dünya senaryolarını ele alacağız.

Süreç Sonlandırma Neden Bu Kadar Önemli?

Linux’ta her çalışan program bir process (süreç) olarak işlem görür. Bu süreçler bazen beklenmedik şekillerde davranır: yanıt vermez, aşırı kaynak tüketir ya da tamamen kilitlenir. İşte bu noktada süreç sonlandırma devreye girer.

Ama “sonlandırma” derken tek bir seçenek yoktur. Linux, süreçlere sinyal göndererek onlarla iletişim kurar. Bu sinyaller SIGTERM gibi nazik bir kapanış isteğinden SIGKILL gibi anında öldürme emrine kadar geniş bir yelpazede yer alır. İyi bir sysadmin, doğru sinyali doğru zamanda kullanmayı bilir.

Sinyal Mekanizması: Temelden Anlayalım

kill komutunu anlamak için önce Linux sinyal sistemini kavramak gerekir. Sinyaller, işletim sisteminin süreçlerle konuşma biçimidir.

En sık kullanılan sinyalleri şöyle özetleyebiliriz:

  • SIGHUP (1): Terminali yeniden bağla veya konfigürasyonu yeniden yükle
  • SIGINT (2): Kesme isteği (Ctrl+C ile gönderilen sinyal)
  • SIGQUIT (3): Çıkış isteği, core dump oluşturabilir
  • SIGKILL (9): Anında öldür, yakalanamaz ve görmezden gelinemez
  • SIGTERM (15): Nazik sonlandırma isteği, varsayılan sinyal
  • SIGSTOP (19): Süreci durdur (dondur), yakalanamaz
  • SIGCONT (18): Durdurulmuş süreci devam ettir
  • SIGUSR1 (10): Kullanıcı tanımlı sinyal 1
  • SIGUSR2 (12): Kullanıcı tanımlı sinyal 2

Peki neden SIGKILL ile başlamıyoruz? Çünkü SIGKILL, sürece temizlik yapma fırsatı vermez. Açık dosyalar kapanmayabilir, geçici dosyalar silinmeyebilir, veritabanı bağlantıları düzgün sonlandırılmayabilir. Bu yüzden önce SIGTERM deneyin, sonra gerekirse SIGKILL’e geçin.

Sistemdeki tüm sinyal listesini görmek için:

kill -l

Bu komut numaraları ve adlarıyla birlikte tüm sinyalleri listeler.

kill Komutu: PID ile Süreç Sonlandırma

kill komutunun adı biraz yanıltıcıdır. Aslında bu komut sadece süreç öldürmez, herhangi bir sinyal gönderir. Ama evet, en çok kullanım amacı süreç sonlandırmaktır.

Temel Kullanım

kill PID

Sinyal belirtmezseniz varsayılan olarak SIGTERM (15) gönderilir. Bu, sürece “lütfen düzgünce kapat kendini” demektir.

# 1234 numaralı sürece SIGTERM gönder
kill 1234

# Aynı işlem, sinyal numarasıyla
kill -15 1234

# Sinyal adıyla
kill -SIGTERM 1234

# Zorla öldür (SIGKILL)
kill -9 1234

# SIGKILL, sinyal adıyla
kill -SIGKILL 1234

PID Nasıl Bulunur?

kill komutunu kullanmadan önce hangi süreci sonlandıracağınızı bilmeniz gerekir. Bunun için birkaç yöntem var:

# Süreç adına göre PID bul
pgrep nginx

# Daha ayrıntılı bilgi için
pgrep -la nginx

# ps ile arama
ps aux | grep firefox

# pidof ile
pidof apache2

Birden Fazla PID’e Aynı Anda Sinyal Gönderme

# Birden fazla süreci aynı anda sonlandır
kill -9 1234 5678 9012

# pgrep çıktısını doğrudan kill'e ver
kill -9 $(pgrep firefox)

Process Group’lara Sinyal Gönderme

Bazı durumlarda bir ana süreç ve onun çocuk süreçlerini birlikte sonlandırmanız gerekebilir. Bunun için process group ID’si (PGID) kullanılır:

# Process group'a sinyal gönder (negatif değer kullanılır)
kill -TERM -1234

# Önce PGID'yi öğren
ps -o pid,pgid,comm -p 1234

killall Komutu: İsimle Süreç Sonlandırma

killall, PID yerine süreç adıyla çalışır. Bu özellikle aynı uygulamanın birden fazla örneği çalışıyorsa çok kullanışlıdır.

Temel Kullanım

# firefox adındaki tüm süreçleri sonlandır
killall firefox

# SIGKILL ile zorla öldür
killall -9 firefox

# Sinyal adıyla
killall -SIGTERM nginx

killall Parametreleri

  • -e: Tam isim eşleşmesi gerektirir (15 karakterden uzun isimler için önemli)
  • -I: Büyük/küçük harf duyarsız eşleştirme
  • -i: Her süreç için onay ister (interaktif mod)
  • -l: Bilinen sinyalleri listeler
  • -q: Sessiz mod, hata mesajı göstermez
  • -r: Regex ile süreç adı eşleştirme
  • -s: Gönderilecek sinyal
  • -u: Belirtilen kullanıcıya ait süreçleri etkiler
  • -v: Sinyal gönderilen her süreç için bilgi verir
  • -w: Tüm süreçler sonlanana kadar bekler
  • -o: Belirtilen süreden daha eski süreçleri etkiler
  • -n: Belirtilen süreden daha yeni süreçleri etkiler
# Sadece belirli kullanıcının süreçlerini sonlandır
killall -u ahmet firefox

# Onay alarak sonlandır (üretim ortamı için faydalı)
killall -i chrome

# Bekleme ile sonlandır (script'lerde kullanışlı)
killall -w nginx

# 1 saatten eski süreçleri sonlandır
killall -o 1h python3

Gerçek Dünya Senaryoları

Teorik bilgi güzel ama asıl öğrenme, gerçek problemleri çözerken gelir. İşte karşılaşacağınız tipik durumlar:

Senaryo 1: Yanıt Vermeyen Web Sunucusu

Nginx bir güncelleme sonrası kilitlendi ve yeni bağlantıları kabul etmiyor. Servis yöneticisi de yanıt vermez hale geldi.

# Önce PID'leri tespit et
pgrep -la nginx

# Nazik kapatma dene
kill -SIGTERM $(pgrep nginx)

# 5 saniye bekle, hala çalışıyor mu kontrol et
sleep 5
pgrep nginx

# Hala çalışıyorsa zorla öldür
kill -9 $(pgrep nginx)

# Servisi yeniden başlat
systemctl start nginx

Senaryo 2: Bellek Yiyen Python Script’i

Bir veri işleme script’i bellek sızıntısı yapıyor ve sistem belleğini tüketiyor.

# En fazla bellek kullanan süreçleri listele
ps aux --sort=-%mem | head -10

# Süreç detaylarını gör
ps aux | grep python3

# PID'yi bulduk, diyelim 8742
# Önce nazikçe dene
kill -15 8742

# Yanıt vermedi, SIGKILL gönder
kill -9 8742

# Alternatif: Tüm python3 süreçlerini öldür (dikkatli ol!)
killall -9 python3

Senaryo 3: Zombie Süreçlerle Başa Çıkma

Zombie süreçler çoktan ölmüş ama process tablosundan silinmemiş süreçlerdir. Bunlar sistem kaynaklarını tüketmez ama PID tablasını doldurur.

# Zombie süreçleri listele
ps aux | grep 'Z'

# Zombie sürecin PPID'sini (parent PID) bul
ps -o pid,ppid,stat,comm | grep Z

# Parent sürece SIGCHLD göndererek zombie temizleme
kill -SIGCHLD PPID

# Parent de yanıt vermiyorsa onu sonlandır
# (parent öldüğünde zombie süreçleri init/systemd devralır ve temizler)
kill -9 PPID

Senaryo 4: Belirli Kullanıcının Tüm Süreçlerini Sonlandırma

Bir kullanıcı sistemi yavaşlatan onlarca süreç çalıştırıyor.

# Kullanıcının tüm süreçlerini listele
ps -u testkullanici

# killall ile kullanıcının tüm süreçlerini sonlandır
killall -u testkullanici

# Daha agresif versiyon
killall -9 -u testkullanici

# pkill ile de yapılabilir
pkill -u testkullanici
pkill -9 -u testkullanici

Senaryo 5: Konfigürasyon Yeniden Yükleme

Bazı servisler konfigürasyon değişikliklerini SIGHUP sinyaliyle yeniden yükleyebilir. Servisi tamamen yeniden başlatmaya gerek kalmaz.

# Nginx konfigürasyonunu yeniden yükle (servis kesintisi olmadan)
kill -HUP $(cat /var/run/nginx.pid)

# Ya da killall ile
killall -HUP nginx

# rsyslog için de aynı yöntem geçerlidir
kill -HUP $(pgrep rsyslogd)

# PostgreSQL için reload
kill -SIGHUP $(head -1 /var/lib/postgresql/data/postmaster.pid)

Senaryo 6: Dondurulmuş Terminalde Stuck Süreç

SSH oturumu bağlantısı kesildi ve arka planda bir süreç devam ediyor. Yeni bağlantıdan temizlemek gerekiyor.

# Eski oturumdaki süreçleri bul
ps aux | grep username

# Terminale bağlı süreçleri göster
ps -t pts/0

# O terminal oturumundaki tüm süreçleri sonlandır
pkill -t pts/0

# Belirli bir süreçse direkt kill
kill -9 PID

pkill: Süreç Sonlandırmanın Üçüncü Yolu

kill ve killall‘dan bahsederken pkill‘i de atlamamak gerekir. pkill, pattern matching ile çalışır ve son derece esnektir.

# İsim pattern'ine göre sonlandır
pkill -f "python manage.py"

# Regex ile eşleştirme
pkill -f "worker_[0-9]+"

# Belirli kullanıcının süreçleri
pkill -u www-data

# Belirli terminal oturumundaki süreçler
pkill -t pts/1

# Kontrol sinyali gönder (SIGUSR1)
pkill -USR1 gunicorn

Script’lerde Güvenli Süreç Sonlandırma

Otomasyon script’leri yazarken süreç sonlandırma işlemini daha zarif yapabilirsiniz:

#!/bin/bash

# Bir süreci güvenli şekilde sonlandıran fonksiyon
graceful_kill() {
    local pid=$1
    local timeout=${2:-30}
    
    # Süreç var mı kontrol et
    if ! kill -0 "$pid" 2>/dev/null; then
        echo "Süreç $pid zaten çalışmıyor"
        return 0
    fi
    
    echo "Sürece SIGTERM gönderiliyor: $pid"
    kill -TERM "$pid"
    
    # Belirtilen süre boyunca bekle
    local waited=0
    while kill -0 "$pid" 2>/dev/null; do
        if [ "$waited" -ge "$timeout" ]; then
            echo "Timeout! SIGKILL gönderiliyor: $pid"
            kill -KILL "$pid"
            return 1
        fi
        sleep 1
        waited=$((waited + 1))
    done
    
    echo "Süreç $pid başarıyla sonlandırıldı"
    return 0
}

# Kullanım
graceful_kill 12345 10

Bu tür bir fonksiyon, production script’lerinde çok değerlidir. Önce nazik davranır, gerekirse sert olur ama hepsini kayıt altına alır.

Dikkat Edilmesi Gereken Durumlar

PID 1’i Asla Öldürmeyin

PID 1, sistemin ana sürecidir (genellikle systemd ya da init). Bunu sonlandırmaya çalışmak sistemi çökertir ya da kernel panik oluşturur. Kernel bu isteği zaten dikkate almaz ama denemeye bile kalkmayın.

kill -9’u Hemen Kullanmayın

SIGKILL bir son çaredir. Veri kaybına, kilitli dosyalara ve yarım kalan işlemlere yol açabilir. Özellikle veritabanı süreçlerinde bunu yapmak ciddi tutarsızlıklara neden olabilir.

Doğru Süreci Öldürdüğünüzden Emin Olun

Özellikle killall kullanırken dikkatli olun. Adı benzer olan başka servisler de etkilenebilir.

# Öldürmeden önce hangi süreçlerin etkileneceğini gör
pgrep -la nginx

# killall ile önce dry-run yap (resmi dry-run yok ama verbose yardımcı olur)
killall -v nginx

# Emin değilseniz PID ile kill kullanın
ps aux | grep nginx
# PID'yi manuel kontrol edin, sonra:
kill -TERM 5432

Root Olmadan Başkasının Süreçlerini Öldüremezsiniz

Normal kullanıcılar yalnızca kendi süreçlerine sinyal gönderebilir. Başka bir kullanıcının sürecine sinyal göndermek için root yetkisi gerekir.

# Bu başarısız olur (root değilseniz ve süreç size ait değilse)
kill -9 1234
# bash: kill: (1234) - Operation not permitted

# sudo ile root yetkisiyle dene
sudo kill -9 1234

Konfigürasyon Sinyalleri ile İleri Düzey Kullanım

Bazı servisler özel sinyallere özel şekillerde tepki verir. Bu bilgi, servisleri kesintisiz yönetmek için kritiktir:

# Apache: Graceful restart (mevcut bağlantıları tamamlar)
kill -USR1 $(cat /var/run/apache2/apache2.pid)

# Nginx: Log rotation sonrası log dosyasını yeniden aç
kill -USR1 $(cat /var/run/nginx.pid)

# Nginx: Binary upgrade (sıfır downtime)
kill -USR2 $(cat /var/run/nginx.pid)

# MySQL: Error log'u yeniden aç
kill -HUP $(pgrep mysqld)

# Redis: RDB snapshot al
kill -USR1 $(pgrep redis-server)

Bu gelişmiş kullanımlar, production ortamlarda kesintisiz servis yönetiminin temel taşıdır.

Süreç İzleme ve Otomatik Tepki

Sadece manuel müdahale değil, otomatik tepki sistemleri de kurabilirsiniz:

#!/bin/bash
# Bellek kullanımı belirli eşiği aşarsa süreci yeniden başlat

SERVICE="myapp"
MAX_MEM_MB=500

while true; do
    PID=$(pgrep -x "$SERVICE")
    
    if [ -z "$PID" ]; then
        echo "Servis çalışmıyor, başlatılıyor..."
        systemctl start "$SERVICE"
    else
        MEM=$(ps -o rss= -p "$PID" | awk '{print $1/1024}')
        echo "Mevcut bellek kullanımı: ${MEM}MB"
        
        if (( $(echo "$MEM > $MAX_MEM_MB" | bc -l) )); then
            echo "Bellek limiti aşıldı! Servis yeniden başlatılıyor..."
            kill -15 "$PID"
            sleep 5
            systemctl start "$SERVICE"
        fi
    fi
    
    sleep 60
done

Sonuç

kill ve killall komutları, Linux sistem yönetiminin olmazsa olmaz araçlarıdır. Ancak bu komutların gücü kadar sorumluluğu da büyüktür. Yanlış süreci ya da yanlış sinyali kullanmak, veri kaybından servis kesintisine kadar ciddi sonuçlar doğurabilir.

Akılda kalması gereken temel prensipler şunlardır: Her zaman önce SIGTERM deneyin, zaman tanıyın, son çare olarak SIGKILL kullanın. Süreç adını değil mümkünse PID’i kullanın, daha güvenlidir. SIGHUP gibi özel sinyalleri servislerin konfigürasyonu yeniden yüklemek için kullanın. Script yazarken graceful shutdown fonksiyonları kullanın. Production ortamında bir süreci öldürmeden önce mutlaka neyi öldürdüğünüzü doğrulayın.

Bu komutları pgrep, pkill, ps ve top gibi araçlarla birleştirdiğinizde, süreç yönetimi konusunda gerçekten güçlü bir araç setine sahip olursunuz. Zamanla hangi sinyali ne zaman kullanacağınız içgüdüsel hale gelir ve sistemle konuşmak çok daha verimli bir hal alır.

Yorum yapın