Sistem yöneticiliğinde en çok kullandığım komutlardan biri ps‘tir. Sunucuda bir şeyler ters gittiğinde, CPU ya da RAM kullanımı tavan yaptığında, ilk içgüdüm terminale geçip ps yazmak olur. Basit görünse de ps komutu, doğru parametrelerle kullanıldığında size süreçler hakkında inanılmaz detaylı bilgi sunar. Bu yazıda ps komutunu tüm yönleriyle ele alacağız: temel kullanımdan ileri düzey filtreleme tekniklerine, gerçek dünya sorun giderme senaryolarına kadar her şeyi konuşacağız.
ps Komutu Nedir ve Nasıl Çalışır?
ps (process status) komutu, Linux çekirdeğinin /proc sanal dosya sisteminden bilgi okuyarak çalışan süreçlerin anlık görüntüsünü sunar. top veya htop gibi sürekli güncellenen araçların aksine, ps komutu çalıştırıldığı andaki durumu yakalar ve çıkar. Bu özellik, özellikle log dosyalarına ya da betiklere çıktı yönlendirirken büyük avantaj sağlar.
ps komutunun iki farklı sözdizimi geleneği vardır. Biri BSD stili (tire işareti olmadan: ps aux), diğeri UNIX/POSIX stili (tek tire ile: ps -ef). İkisi de yaygın kullanılır ve çoğu durumda benzer bilgileri gösterir. Hangisini kullandığınız genellikle alışkanlık meselesidir, ancak ikisini de bilmek önemli.
Temel Kullanım
Hiç parametre vermeden çalıştırdığınızda ps, yalnızca mevcut terminal oturumundaki süreçleri gösterir:
ps
Bu çıktı genellikle çok kısıtlıdır ve sadece bash ile ps süreçlerini listeler. Gerçek hayatta bu kadarla yetinmeyiz.
Tüm Süreçleri Listeleme
Sistemdeki tüm süreçleri görmek için iki yaygın yol vardır:
# BSD stili - en yaygın kullanım
ps aux
# UNIX stili
ps -ef
ps aux çıktısındaki sütunları tanıyalım:
- USER: Süreci başlatan kullanıcı
- PID: Süreç kimlik numarası (Process ID)
- %CPU: CPU kullanım yüzdesi
- %MEM: Bellek kullanım yüzdesi
- VSZ: Sanal bellek boyutu (KB cinsinden)
- RSS: Gerçek fiziksel bellek kullanımı (KB cinsinden)
- TTY: Bağlı olduğu terminal (? işareti daemon süreçleri için)
- STAT: Süreç durumu
- START: Sürecin başlangıç zamanı
- TIME: Toplam CPU süresi
- COMMAND: Çalıştırılan komut
ps -ef ile gelen ek sütun ise PPID‘dir, yani üst süreç (parent process) kimliği. Bu, süreç hiyerarşisini anlamak için kritik öneme sahiptir.
Süreç Durumları (STAT Sütunu)
STAT sütunundaki harfler size sürecin o an ne yaptığını söyler. Bunları bilmek, sorun gidermede çok işe yarar:
- R: Çalışıyor veya çalışmaya hazır (Running)
- S: Kesintiye uğrayabilir uyku durumu, genellikle bir olayı bekliyor (Sleeping)
- D: Kesintiye uğramaz uyku, disk I/O bekliyor (Uninterruptible sleep)
- Z: Zombie süreç, üst süreç tarafından toplanmamış
- T: Durdurulmuş, genellikle Ctrl+Z ile
- I: Boşta çekirdek süreci
Ek karakterler de görebilirsiniz:
- <: Yüksek öncelikli süreç
- N: Düşük öncelikli süreç (nice değeri pozitif)
- l: Çoklu iş parçacıklı süreç
- +: Ön planda çalışan süreç
Pratik Filtreleme Teknikleri
Belirli Bir Kullanıcının Süreçlerini Görmek
# Belirli bir kullanıcının süreçleri
ps -u nginx
ps -u www-data
ps -u deploy
# Birden fazla kullanıcı
ps -u nginx,mysql,redis
Bu, bir web sunucusunda her servisin kendi kullanıcısıyla çalıştığından emin olmak için harika bir yöntemdir. Güvenlik açısından nginx süreçlerinin root ile değil, nginx veya www-data kullanıcısıyla çalışması gerekir.
Belirli Bir Süreci İsimle Aramak
# grep ile filtreleme
ps aux | grep nginx
ps aux | grep python
ps aux | grep -v grep | grep nginx # grep sürecini çıktıdan kaldırır
grep kullanırken klasik bir tuzak vardır: ps aux | grep nginx çıktısında hem nginx süreci hem de grep komutunun kendisi görünür. Bunu önlemek için birkaç yöntem var:
# Yöntem 1: grep sürecini hariç tut
ps aux | grep [n]ginx
# Yöntem 2: pgrep kullan (daha temiz)
pgrep -l nginx
Köşeli parantez hilesi güzel bir trick’tir. [n]ginx pattern’ı nginx süreçlerini yakalar ama grep komutunun kendisi [n]ginx string’ini içermediği için çıktıya dahil olmaz.
PID ile Süreç Sorgulama
# Belirli bir PID'in detayları
ps -p 1234
ps -p 1234,5678,9012
# Süreç ağacını göster
ps -p 1234 -f
Süreç Ağacını Görselleştirme
# ps ile süreç ağacı
ps auxf
# Sadece belirli bir sürecin alt süreçleri
ps --ppid 1234
ps auxf çıktısında COMMAND sütununda girintileme göreceksiniz. Bu, hangi sürecin hangi süreci başlattığını net biçimde ortaya koyar. Örneğin bir Apache sunucusunda ana httpd süreci ve onun altındaki worker process’leri görmek için idealdir.
Çıktıyı Özelleştirme: -o Parametresi
ps komutunun en güçlü özelliklerinden biri, görmek istediğiniz sütunları kendiniz seçebilmenizdir:
# Sadece PID, kullanıcı ve komut
ps -eo pid,user,cmd
# CPU ve bellek odaklı görünüm
ps -eo pid,user,%cpu,%mem,rss,cmd --sort=-%cpu
# Süreç başlangıç zamanıyla birlikte
ps -eo pid,user,lstart,cmd
# Çalışma süresiyle birlikte
ps -eo pid,user,etime,cmd
Sık kullandığım özel format şudur:
ps -eo pid,ppid,user,%cpu,%mem,stat,start,time,cmd --sort=-%mem | head -20
Bu komut, bellek kullanımına göre sıralanmış ilk 20 süreci gösterir. Bellek sızıntısı şüphelendiğinizde ilk bakacağınız şey bu olmalı.
Sıralama Seçenekleri
# CPU kullanımına göre azalan sırada
ps aux --sort=-%cpu | head -10
# Bellek kullanımına göre azalan sırada
ps aux --sort=-%mem | head -10
# PID'e göre sıralama (süreç başlangıç sırasına yakın)
ps aux --sort=pid
# Çalışma süresine göre
ps -eo pid,user,etime,cmd --sort=-etime | head -10
Gerçek Dünya Senaryoları
Senaryo 1: Sunucu Yavaşladı, Suçluyu Bul
Sabah erken saatte monitoring sisteminden alarm geldi. Sunucunun load average’ı 20’ye fırlamış. SSH bağlanıp ilk yapacağın şey:
# CPU'yu en çok kim yiyor?
ps aux --sort=-%cpu | head -15
# Zombie süreç var mı kontrol et
ps aux | grep -w Z
# D durumundaki (disk I/O bekleyen) süreçler
ps aux | awk '$8 ~ /D/ {print}'
# Aynı anda kaç nginx worker var?
ps aux | grep -c [n]ginx
Diyelim ki çıktıda bir PHP-FPM sürecinin %200 CPU yediğini gördünüz. Bu, sonsuz döngüye girmiş bir PHP scripti anlamına gelebilir. PID’i not alıp önce strace ile inceleyebilir, ardından gerekirse sonlandırabilirsiniz.
Senaryo 2: Bellek Sızıntısı Tespiti
Bir uygulama sunucusunda hafızanın yavaş yavaş dolduğu raporlandı. Günlük periyodik kontrol için şunu kullanabilirsiniz:
# Java uygulamalarının bellek kullanımı
ps -eo pid,user,%mem,rss,cmd | grep java | sort -k3 -rn
# Belirli bir sürecin zaman içindeki bellek değişimi (bash döngüsüyle)
while true; do
ps -p 12345 -o pid,%mem,rss --no-headers
sleep 60
done
RSS değerinin (gerçek fiziksel bellek) saatler içinde sürekli artıp azalmadan büyüdüğünü görüyorsanız, bellek sızıntısı var demektir.
Senaryo 3: Güvenlik Denetimi
Sisteme yetkisiz erişim şüphesi var. Beklenmedik süreçleri tespit etmek için:
# Root dışında hangi kullanıcılar süreç çalıştırıyor?
ps -eo user,pid,cmd | sort -u | grep -v root | grep -v systemd
# Olağandışı port dinleyen süreçler (ps + netstat/ss kombinasyonu)
ps -eo pid,user,cmd | grep -E "(nc|ncat|netcat|socat)"
# Gizli dizinlerden çalışan süreçler
ps aux | grep -E "/tmp|/dev/shm|/var/tmp"
# Yeni başlatılmış süreçler (son 1 saat içinde)
ps -eo pid,user,lstart,cmd | grep "$(date '+%b %e')"
/tmp veya /dev/shm altından çalışan süreçler ciddi bir kırmızı bayraktır. Meşru uygulamalar bu dizinlerden executable çalıştırmaz.
Senaryo 4: Zombie Süreçlerle Başa Çıkma
Zombie süreçler kaynak tüketmez ama PID tablosunu doldurabilir ve üst süreçte bir sorun olduğuna işaret ederler:
# Zombie süreçleri listele
ps aux | awk '$8 == "Z"'
# Zombie'nin üst sürecini bul
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/ {print $0}'
# Üst sürece SIGCHLD gönder (zombie'yi temizlemeye zorlar)
kill -SIGCHLD <parent_pid>
Çok sayıda zombie süreç görüyorsanız ve üst sürece sinyal göndermek işe yaramıyorsa, üst süreci yeniden başlatmanız gerekebilir.
Senaryo 5: Cron Job Takibi
Bir cron job’ın çalışıp çalışmadığını kontrol etmek:
# Cron tarafından başlatılan süreçleri bul
ps aux | grep cron
ps -eo pid,ppid,user,cmd | awk '$2 == <cron_pid>'
# Belirli bir scriptin çalışıp çalışmadığı
ps aux | grep backup.sh | grep -v grep
# Ne zaman başladığını öğren
ps -eo pid,lstart,cmd | grep backup.sh | grep -v grep
ps Komutunu Betiklerde Kullanmak
ps çıktısını betiklerde işlerken bazı püf noktaları vardır:
#!/bin/bash
# Bellek kullanımı yüzde 80'i geçen süreçleri raporla
THRESHOLD=80
ps -eo pid,user,%mem,cmd --no-headers | while read pid user mem cmd; do
mem_int=${mem%.*}
if [ "$mem_int" -gt "$THRESHOLD" ] 2>/dev/null; then
echo "UYARI: PID $pid ($user) - $mem% bellek kullanıyor: $cmd"
fi
done
--no-headers parametresi, çıktının ilk satırındaki başlık satırını kaldırır. Betiklerde çıktıyı parse ederken bu şart.
Bir başka kullanışlı örnek, bir servisin belirli sayıda instance’ın üzerinde çalışıp çalışmadığını kontrol etmek:
#!/bin/bash
# nginx worker sayısını kontrol et
PROCESS="nginx"
MAX_WORKERS=10
count=$(ps aux | grep -c [n]ginx)
if [ "$count" -gt "$MAX_WORKERS" ]; then
echo "$(date): nginx worker sayısı $count - beklenen maksimum: $MAX_WORKERS" >> /var/log/process_monitor.log
fi
Faydalı ps Takma Adları (Aliases)
.bashrc veya .bash_profile dosyanıza şu takma adları ekleyerek işinizi kolaylaştırabilirsiniz:
# En çok CPU kullanan 10 süreç
alias pscpu='ps aux --sort=-%cpu | head -11'
# En çok bellek kullanan 10 süreç
alias psmem='ps aux --sort=-%mem | head -11'
# Süreç ağacı görünümü
alias pstree='ps auxf'
# Belirli bir süreç ara (zombie grep sorununu çözerek)
psfind() {
ps aux | grep "[${1:0:1}]${1:1}"
}
psfind nginx yazdığınızda hem grep hilesi otomatik uygulanır hem de temiz bir çıktı alırsınız.
ps vs Alternatif Araçlar
ps her iş için en iyi araç olmayabilir. Hangi durumda ne kullanacağınızı bilmek önemli:
- ps: Anlık görüntü, betik entegrasyonu, filtreleme ve özel format için ideal
- top / htop: Gerçek zamanlı izleme, interaktif kullanım için
- pgrep: Sadece PID bulmak için daha temiz çıktı verir
- pstree: Süreç hiyerarşisini görselleştirmek için daha iyi
- pidof: Bir programın PID’ini hızlıca öğrenmek için
- lsof: Süreçlerin hangi dosyaları ve portları kullandığını görmek için
Örneğin bir servisin PID’ini bulmak için ps aux | grep nginx yazmak yerine doğrudan pidof nginx veya pgrep nginx yazmak daha hızlıdır. Ama servis hakkında detaylı bilgi (CPU, bellek, başlangıç zamanı) istiyorsanız ps alternatifsizdir.
ps Çıktısını Kayıt Altına Alma
Olay sonrası analiz (post-mortem) için süreç durumunu periyodik olarak kayıt altına almak iyi bir pratiktir:
# Her 5 dakikada bir süreç durumunu logla
*/5 * * * * ps aux --no-headers >> /var/log/ps_snapshot.log
# Tarihi de ekleyerek
*/5 * * * * echo "=== $(date) ===" >> /var/log/ps_snapshot.log && ps aux >> /var/log/ps_snapshot.log
Bu basit cron job, bir sorun yaşandığında “o sırada sistem ne yapıyordu?” sorusuna cevap vermenizi sağlar. Production ortamlarında bu tür geçmiş veriler çok değerlidir.
Önemli Parametreler Özeti
Sık kullanılan ps parametrelerini hatırlamak için özet:
- a: Tüm kullanıcıların süreçlerini göster (BSD stili)
- u: Kullanıcı odaklı format (CPU, bellek bilgileriyle)
- x: Terminal bağlı olmayan süreçleri de dahil et
- f: ASCII sanat ile süreç ağacı (forest)
- e: Tüm süreçleri göster (UNIX stili,
aile eşdeğer) - -f: Tam format (PPID sütunu dahil)
- -u kullanici: Belirli kullanıcının süreçleri
- -p pid: Belirli PID
- -o format: Özel çıktı formatı
- –sort=kolon: Belirli kolona göre sıralama
- –no-headers: Başlık satırını kaldır (betikler için)
- –forest: Süreç ağacı görünümü (uzun format)
Sonuç
ps komutu, ilk bakışta basit görünen ama derinleştikçe ne kadar güçlü olduğunu anlayan bir araçtır. Temel ps aux kullanımından özel format tanımlamaya, grep hileleri ve betik entegrasyonuna kadar geniş bir kullanım yelpazesi sunar. Sistem yöneticiliğinde “neler oluyor burada?” sorusunun cevabı çoğu zaman ps çıktısında gizlidir.
Benim tavsiyem şu: bu komutun temel parametrelerini ezberleyin ama -o ile özel format oluşturmayı da mutlaka öğrenin. Her sorun senaryosu farklı bilgi gerektirir ve ihtiyacınıza göre özelleştirilmiş bir ps sorgusu, sayfalar dolusu genel çıktıyı incelemekten çok daha verimlidir. Kendi .bashrc dosyanıza en sık kullandığınız alias’ları ekleyin ve zaman içinde bu komut adeta ikinci doğanız haline gelecektir.