Bir sunucuda çalışan uygulamalar zaman zaman kilitlenir, belleği tüketmeye başlar ya da yanıt vermeyi keser. Böyle anlarda çoğu kişinin ilk refleksi "hemen kill -9 gönderelim, bitsin gitsin" olur. Oysa bir süreci sonlandırmak, elektrik fişini duvardan çekmek gibi düşünülmemeli. Linux'ta süreçler birbirleriyle ve çekirdekle sinyaller aracılığıyla haberleşir; doğru sinyali doğru anda göndermek, yalnızca uygulamayı kapatmakla kalmaz, verinizin bozulmadan diske yazılmasını, açık dosyaların düzgün kapanmasını ve alt süreçlerin ardında yetim kalmamasını da sağlar.
Bu rehberde bir sistem yöneticisinin günlük hayatta en çok kullandığı araçları ele alacağız: kill, pkill ve killall. Bir sürecin kimliğini (PID) nasıl bulacağınızı, SIGTERM ile SIGKILL arasındaki kritik farkı, hangi durumda hangi sinyali tercih etmeniz gerektiğini ve zombi ile "kesilemeyen" (uninterruptible) süreçlerin neden kill -9 ile bile ölmediğini adım adım göreceğiz. Amaç, panik anında körlemesine komut yazmak yerine ne yaptığını bilerek, veriyi ve servisin bütünlüğünü koruyarak müdahale etmenizi sağlamak.
Süreç Nedir ve PID Nasıl Bulunur#
Linux'ta çalışan her program bir süreç (process) olarak ifade edilir ve her sürecin benzersiz bir kimlik numarası vardır: PID (Process ID). Bir süreci sonlandırmak istiyorsanız önce doğru PID'yi bulmanız gerekir; çünkü kill komutu esasen bir PID'ye sinyal gönderir. Yanlış PID'ye sinyal göndermek, çalışan başka bir servisi düşürmek anlamına gelebilir, bu yüzden bu adımı özenle yapmak gerekir.
En yaygın yöntem ps çıktısını filtrelemektir. Örneğin takılmış bir nginx sürecini aradığınızı varsayalım:
# Tüm süreçleri geniş formatta listele ve nginx içerenleri süz
ps aux | grep nginx
# Yalnızca PID döndüren daha temiz yöntem
pgrep nginx
# Süreç adı, kullanıcı ve komut satırıyla birlikte
pgrep -a nginx
ps aux çıktısında ikinci sütun PID'dir. Alternatif olarak pgrep doğrudan PID listesi verdiği için betiklerde çok daha güvenilirdir. Bir portu dinleyen süreci arıyorsanız ss veya lsof işinizi görür:
# 8080 portunu hangi süreç dinliyor
ss -ltnp 'sport = :8080'
# Belirli bir dosyayı hangi süreç açık tutuyor
lsof /var/log/app/output.log
Anlık kaynak tüketimini görüp oradan müdahale etmek isterseniz top veya htop içinde CPU'yu ya da belleği kemiren süreci tespit edip PID'sini not edebilirsiniz. Temel süreç ve dosya komutlarını daha derinlemesine görmek isterseniz Linux temel komutları rehberimize göz atabilirsiniz.
kill Komutunun Söz Dizimi#
İsminin yanıltıcılığına aldanmayın: kill aslında "öldüren" değil, "sinyal gönderen" bir komuttur. Varsayılan davranışı SIGTERM (sinyal 15) göndermektir ve bu, sürece "işini toparla ve düzgünce kapan" demenin nazik yoludur. Temel kullanım şöyledir:
# Varsayılan sinyal (SIGTERM / 15) gönder
kill 4823
# Sinyali numarayla belirt
kill -15 4823
# Sinyali ismiyle belirt (SIG öneki isteğe bağlı)
kill -TERM 4823
kill -SIGTERM 4823
# Aynı anda birden fazla PID'ye
kill -15 4823 4824 4825
Sistemin desteklediği tüm sinyalleri listelemek için -l bayrağını kullanabilirsiniz:
# Sinyal numaralarını ve isimlerini listele
kill -l
# Belirli bir numaranın hangi sinyal olduğunu öğren
kill -l 9 # KILL döndürür
Burada dikkat edilmesi gereken bir yetki konusu var. Bir süreci sonlandırabilmeniz için ya o sürecin sahibi olmanız ya da root olmanız gerekir. Başka bir kullanıcının süreci ise sudo ile hareket etmelisiniz:
# Başka kullanıcıya ait süreç için yetki yükselt
sudo kill -15 4823
Yetkiniz yoksa çekirdek sinyali reddeder ve "Operation not permitted" hatası alırsınız. Bu, kötü niyetli bir kullanıcının başkasının süreçlerini keyfi olarak düşürmesini engelleyen bilinçli bir güvenlik sınırıdır.
SIGTERM ve SIGKILL Arasındaki Fark#
Bu bölüm, tüm rehberin kalbidir. İki sinyal arasındaki farkı içselleştirdiğinizde, süreç sonlandırma konusunda vereceğiniz her karar netleşir.
SIGTERM (15) yakalanabilir bir sinyaldir. Yani uygulamanın kendisi bu sinyali dinleyip "tamam, kapanıyorum" diyebilir. İyi yazılmış bir program SIGTERM aldığında açık veritabanı bağlantılarını kapatır, bellekteki tamponları (buffer) diske yazar (flush), geçici dosyaları temizler ve ancak ondan sonra sonlanır. Bu, veri bütünlüğü için hayati önem taşır.
SIGKILL (9) ise yakalanamaz, engellenemez ve göz ardı edilemez. Bu sinyali doğrudan Linux çekirdeği işler; süreç bunu duymaz bile. Çekirdek, süreci hiçbir temizlik yapmasına fırsat vermeden, o anki durumunda anında öldürür. Bellekteki henüz yazılmamış veriler kaybolur, kilitler ortada kalabilir, geçici dosyalar birikir.
Aradaki farkı bir tablo ile netleştirelim:
| Özellik | SIGTERM (15) | SIGKILL (9) |
|---|---|---|
| Uygulama yakalayabilir mi | Evet | Hayır |
| Temizlik/kaydetme fırsatı | Var | Yok |
| Veri kaybı riski | Düşük | Yüksek |
| Çekirdek zorla uygular mı | Hayır | Evet |
| Önerilen ilk seçim | Evet | Hayır |
| Ne zaman | Her zaman önce | Yalnızca çaresiz kalınca |
Doğru yaklaşım her zaman kademelidir. Önce nazik olanı deneyin, süreç makul bir süre içinde kapanmazsa sertine geçin:
# 1. Önce nazikçe iste
kill -15 4823
# 2. Birkaç saniye bekle ve süreç hâlâ var mı diye kontrol et
sleep 5
ps -p 4823
# 3. Hâlâ yaşıyorsa son çare
kill -9 4823
kill -9'u reflekse dönüştürmemek çok önemlidir. Bir veritabanı sunucusunu (MySQL, PostgreSQL) SIGKILL ile düşürmek, açık işlemlerin (transaction) yarıda kalmasına ve bir sonraki açılışta çökme kurtarma (crash recovery) sürecine yol açabilir; kötü senaryolarda tablo bozulması bile mümkündür. Bu yüzden veritabanı ve benzeri servisleri her zaman kendi düzgün kapatma mekanizmalarıyla ya da systemctl stop ile durdurmak en güvenlisidir. Servis yönetimini systemd servis yönetimi rehberinde ayrıntılı bulabilirsiniz.
Sinyal Numaraları ve Anlamları#
SIGTERM ve SIGKILL en çok kullanılanlar olsa da, bir yöneticinin günlük hayatta işine yarayan başka sinyaller de vardır. Bunların bir kısmı sürecin davranışını değiştirmek için, bir kısmı ise duraklatıp devam ettirmek için kullanılır. En sık karşılaşacağınızları bir tabloda toplayalım:
| Sinyal | Numara | Anlamı ve Tipik Kullanım |
|---|---|---|
| SIGHUP | 1 | Yapılandırmayı yeniden yükle (nginx, sshd) |
| SIGINT | 2 | Klavyeden kesme, Ctrl+C ile aynı |
| SIGQUIT | 3 | Çekirdek dökümüyle çık, Ctrl+Backslash |
| SIGKILL | 9 | Zorla ve anında sonlandır |
| SIGTERM | 15 | Nazikçe sonlandırma isteği (varsayılan) |
| SIGSTOP | 19 | Süreci duraklat (yakalanamaz) |
| SIGCONT | 18 | Duraklatılmış süreci devam ettir |
| SIGUSR1 | 10 | Uygulamaya özel, sıklıkla log döndürme |
Özellikle SIGHUP çok pratiktir. Birçok servis, yapılandırma dosyasını değiştirdikten sonra tamamen yeniden başlatmadan (dolayısıyla hizmeti kesmeden) ayarları yeniden okumak için SIGHUP dinler:
# nginx yapılandırmasını kesintisiz yeniden yükle
kill -HUP $(cat /run/nginx.pid)
# ya da doğrudan
nginx -s reload
Bir süreci öldürmeden geçici olarak dondurmak isterseniz SIGSTOP ve SIGCONT ikilisini kullanabilirsiniz. Örneğin diski aşırı yoran bir yedekleme işini geçici olarak duraklatıp, yoğunluk azalınca kaldığı yerden sürdürebilirsiniz:
# Süreci dondur
kill -STOP 5120
# Daha sonra kaldığı yerden devam ettir
kill -CONT 5120
Bu esneklik, kill komutunu basit bir "öldürme" aracının çok ötesine taşır; aslında süreç yaşam döngüsünü yöneten bir denetim aracıdır.
pkill ve killall ile İsimle Sonlandırma#
Her seferinde PID bulup sonra kill çağırmak zahmetli olabilir. pkill ve killall, süreçleri doğrudan isimleriyle hedeflemenizi sağlar. İkisi benzer işi yapar ama önemli bir davranış farkları vardır.
pkill, komut adının bir kısmıyla eşleşir (desen tabanlı çalışır), killall ise varsayılan olarak tam isim eşleşmesi arar. Bu ayrım pratikte çok önemlidir:
# İsimde "php" geçen TÜM süreçlere SIGTERM
pkill php
# Tam olarak "php-fpm" adlı süreçlere
killall php-fpm
# Belirli bir kullanıcının süreçlerini hedefle
pkill -u www-data
# İsimle ama sert sinyalle
killall -9 stuck-daemon
pkill -9 -f "python worker.py"
pkill -f bayrağı özellikle güçlüdür: yalnızca süreç adına değil, tüm komut satırına bakar. Aynı ikili dosyanın farklı argümanlarla çalışan birçok örneği varsa, doğru olanı ayırt etmenizi sağlar:
# Yalnızca belirli argümanla çalışan Python işçisini sonlandır
pkill -f "manage.py runworker"
Bu araçların gücü aynı zamanda tehlikesidir. pkill deseni fazla geniş tutulursa, hedeflemediğiniz süreçleri de düşürebilirsiniz. Örneğin pkill ssh yazarken, mevcut SSH oturumunuzu da kesip kendinizi sunucudan atma riskiniz vardır. Bu yüzden gerçekten öldürmeden önce hangi süreçlerin eşleştiğini kuru çalışma ile görmek altın kuraldır:
# Öldürmeden önce hangi süreçler eşleşiyor gör (-l isim de yazar)
pkill -l -f "manage.py"
# Sadece PID listesini önizle
pgrep -a -f "manage.py"
Bir sürecin tüm örneklerini toplu kapatırken, önce pgrep ile listeyi doğrulamak, sonra aynı deseni pkille vermek en güvenli iş akışıdır. Böylece "yanlış süreci düşürdüm" kazalarının önüne geçersiniz.
Zombi ve Savunmasız Süreçler#
Bazen bir süreç kill -9 gönderdiğinizde bile ölmez ve bu çoğu yöneticiyi ilk kez şaşırtır. Bunun iki tipik nedeni vardır: zombi süreçler ve kesilemeyen (uninterruptible) süreçler.
Zombi süreç aslında zaten ölmüş bir süreçtir. İşini bitirmiş, ama çıkış durumunu (exit status) ebeveyn sürecinin okumasını bekliyordur. ps çıktısında durum sütununda Z harfiyle görünür ve <defunct> etiketi taşır. Zombi bir sürece sinyal göndermenin bir anlamı yoktur; çünkü zaten çalışmıyordur, yalnızca süreç tablosunda bir kayıt olarak duruyordur. Çözüm, ebeveyni bulup onu düzeltmektir:
# Zombi süreçleri bul (durum Z)
ps aux | awk '$8 ~ /Z/ { print $2, $11 }'
# Bir zombinin ebeveynini (PPID) öğren
ps -o ppid= -p 6210
Zombi'yi doğrudan öldüremezsiniz; ancak ebeveynine SIGCHLD göndererek çıkış durumunu okumasını (reap) tetikleyebilir ya da ebeveyni yeniden başlatabilirsiniz. Ebeveyn ölürse, zombi init/systemd (PID 1) tarafından sahiplenilir ve kısa sürede temizlenir. Az sayıda zombi zararsızdır; sürekli birikiyorsa bu, ebeveyn uygulamanın alt süreçlerini düzgün toplamadığına işaret eden bir yazılım hatasıdır.
Kesilemeyen süreç ise durum sütununda D harfiyle görünür ve genellikle bir donanım ya da ağ işleminde (disk G/Ç, yanıt vermeyen bir NFS bağlaması gibi) çekirdek seviyesinde beklerken kilitlenmiştir. SIGKILL bile bir süreci ancak çekirdek onu bu bekleme durumundan çıkardığında etkiler; D durumundaki süreç hiçbir sinyali işleyemez. Burada yapılacak şey aslında kök nedeni gidermektir: takılan diski ya da NFS bağlamasını düzeltmek, çoğu zaman sürecin kendiliğinden çözülmesini sağlar.
# Kesilemeyen (D durumu) süreçleri bul
ps -eo pid,stat,comm | awk '$2 ~ /D/'
Bu iki durumun ortak dersi şudur: kill -9'un çalışmaması her zaman yetki sorunu değildir. Bazen süreç zaten ölüdür, bazen de çekirdek onu geçici olarak "dokunulmaz" hâle getirmiştir.
Nazik Kapatma Önceliği ve Güvenli Yaklaşım#
Deneyimli yöneticilerin ortak alışkanlığı, süreç sonlandırmayı bir sıralama olarak görmektir: en az yıkıcı yöntemden başlayıp gerektikçe sertleşmek. Bu yaklaşım, özellikle üretim (production) sunucularında veri kaybını ve hizmet kesintisini en aza indirir.
Pratik bir karar sıralaması şöyle özetlenebilir:
- Önce servisi kendi yöneticisiyle durdurmayı deneyin:
systemctl stop servis-adi. Bu, uygulamanın tasarlanmış kapatma yolunu izler. - Servis yöneticisi yoksa SIGTERM gönderin:
kill -15 PID. Uygulamaya toparlanma şansı verir. - Birkaç saniye bekleyip sürecin gerçekten kapandığını doğrulayın.
- Yalnızca süreç yanıt vermiyorsa SIGKILL'e geçin:
kill -9 PID.
Bir betikte bu mantığı otomatikleştirmek isterseniz, "önce nazik, sonra sert" desenini tek bir akışta uygulayabilirsiniz:
#!/usr/bin/env bash
PID=4823
# Süreç var mı diye kontrol edip nazik sinyal gönder
if kill -0 "$PID" 2>/dev/null; then
kill -TERM "$PID"
# 10 saniyeye kadar düzgün kapanmasını bekle
for i in $(seq 1 10); do
kill -0 "$PID" 2>/dev/null || exit 0
sleep 1
done
# Hâlâ ayaktaysa zorla sonlandır
kill -KILL "$PID"
fi
Buradaki kill -0, aslında hiçbir sinyal göndermez; yalnızca sürecin var olup olmadığını ve ona sinyal gönderme yetkinizin bulunup bulunmadığını sınamak için kullanılan zarif bir tekniktir. Bir sürecin hâlâ yaşayıp yaşamadığını kontrol etmenin en temiz yoludur.
Son bir uyarı: bir süreci sonlandırmadan önce neden takıldığını anlamaya çalışmak, çoğu zaman körlemesine öldürmekten daha değerlidir. Yüksek CPU'yu bir sonsuz döngü mü tetikliyor, bellek bir sızıntıdan mı doluyor, yoksa yavaş bir sorgu mu servisi kilitledi? Sunucularınızın kaynak grafiklerini ve süreç durumunu düzenli izlemek, bu kararları çok daha bilinçli almanızı sağlar. Yönetimini bize bırakmak isteyen işletmeler için sunucu yönetimi hizmetlerimiz tam da bu proaktif izleme ve müdahale işini üstlenir.
Sıkça Sorulan Sorular#
kill -9 ile kill -15 arasındaki fark nedir?#
Aralarındaki temel fark, uygulamanın sinyale tepki verip veremeyeceğidir. kill -15 (SIGTERM) yakalanabilir bir istektir; uygulama bunu duyup verilerini kaydeder, bağlantılarını kapatır ve düzgünce sonlanır. kill -9 (SIGKILL) ise doğrudan çekirdek tarafından uygulanır, süreç bunu duymaz bile ve hiçbir temizlik yapamadan anında ölür. Bu yüzden her zaman önce 15 denenmeli, ancak süreç yanıt vermezse 9'a geçilmelidir.
Süreç kill -9 gönderdiğim hâlde neden ölmüyor?#
Bunun iki yaygın nedeni vardır. Birincisi, sürecin zaten bir zombi (durum Z) olmasıdır; bu durumda süreç aslında ölmüştür ve yalnızca ebeveyni çıkış durumunu okuyana kadar tabloda bir kayıt olarak durur, dolayısıyla ona sinyal göndermenin etkisi olmaz. İkincisi, sürecin kesilemeyen uyku (durum D) hâlinde olmasıdır; genellikle takılan bir disk ya da NFS işlemi beklerken çekirdek onu geçici olarak sinyallere kapatır. Her iki durumda da çözüm süreci değil, kök nedeni (ebeveyn süreç ya da donanım) düzeltmektir.
pkill ile killall arasında ne fark var?#
İkisi de süreçleri isme göre hedefler ama eşleşme mantıkları farklıdır. pkill varsayılan olarak süreç adının bir kısmıyla desen eşleşmesi yapar ve -f bayrağıyla tüm komut satırına bakabilir, bu da onu daha esnek kılar. killall ise varsayılan olarak tam isim eşleşmesi arar. Geniş desen tehlikeli olabileceğinden, her ikisinde de öldürmeden önce pgrep veya pkill -l ile hangi süreçlerin eşleştiğini önizlemek en güvenli yöntemdir.
Bir servisi kill yerine nasıl durdurmalıyım?#
Bir servis systemd altında yönetiliyorsa, doğrudan sinyal göndermek yerine systemctl stop servis-adi komutunu kullanmak her zaman daha güvenlidir. Bu komut, servisin birim dosyasında tanımlanmış düzgün kapatma yolunu izler, alt süreçleri de temiz şekilde toplar ve gerektiğinde belirlenmiş bir zaman aşımından sonra otomatik olarak SIGKILL'e yükseltir. Özellikle veritabanları ve web sunucuları için bu yöntem, veri bütünlüğünü koruyan tercih edilen yaklaşımdır.
Yanlış PID'ye sinyal göndermekten nasıl korunurum?#
En etkili korunma, sonlandırmadan önce hedefi doğrulamaktır. pgrep -a desen veya ps -p PID -o pid,user,cmd komutlarıyla o kimliğin gerçekten hedeflediğiniz süreç olduğunu görün. İsimle çalışırken pkill -l -f ile kuru bir önizleme yapın ve desenlerinizi mümkün olduğunca dar tutun. Ayrıca kritik işlemlerde kill -0 PID ile sürecin varlığını ve yetkinizi sinyal göndermeden test edebilirsiniz; bu, körlemesine komut yazmanın önüne geçer.
Kapanış#
Süreç sonlandırma, ilk bakışta basit bir kill komutundan ibaret görünse de, arka planda veri bütünlüğü, servis kararlılığı ve sistem sağlığı gibi ciddi konular yatar. Anahtar ilke sabittir: önce nazik davranın (SIGTERM ve systemctl stop), süreç yanıt vermezse zorlayın (SIGKILL) ve kill -9 ile bile ölmeyen süreçlerde kök nedene odaklanın. Bu kademeli yaklaşımı benimsediğinizde, panik anlarında bile sunucunuza zarar vermeden müdahale edebilirsiniz.
Bu tür işletim ve bakım yükünü tamamen uzman bir ekibe devretmek isterseniz, Clou.TR olarak yanınızdayız. Yüksek performanslı sanal ve fiziksel sunucularımızdan yönetimli VDS çözümlerimize, 7/24 izleme sunan sunucu yönetimi hizmetimizden hız ve güvenlik odaklı hosting paketlerimize kadar tüm altyapınızı güvenle emanet edebileceğiniz seçenekler sunuyoruz. Doğru sinyali göndermeyi öğrendiniz; şimdi sıra bu bilgiyi kesintisiz çalışan sağlam bir altyapı üzerinde uygulamakta.