ps ile Çalışan Süreçleri Listeleme ve Filtreleme

Sunucuda bir şeyler ters gittiğinde, ilk içgüdün ne olur? Benim her zaman terminalı açıp süreçlere bakmak olmuştur. Ve bu işin en temel aracı, yıllardır değişmeyen, her Linux dağıtımında seni karşılayan ps komutudur. Basit görünür, ama içinde gerçekten derinleşince “bu kadar mı vardı?” diye şaşırırsın. Bu yazıda ps komutunu sadece teorik olarak değil, gerçek dünya senaryolarıyla birlikte ele alacağız.

ps Nedir ve Neden Hala Kullanıyoruz?

ps (process status), sistemde o an çalışan süreçler hakkında anlık bir fotoğraf çeker. top veya htop gibi araçlar dinamik ve sürekli güncellenen bir görünüm sunarken, ps tek seferlik, betiklere gömülebilir, çıktısı parse edilebilir bir araçtır. Otomasyon yazıyorsan, cron job hazırlıyorsan veya bir şeyin çalışıp çalışmadığını kontrol eden bir script kuruyorsan ps senin arkadaşındır.

Ayrıca ps çıktısını grep, awk, sort, kill gibi komutlarla zincirleyebilirsin. Bu esneklik, onu sistem yöneticileri için vazgeçilmez kılar.

Temel Kullanım ve Sözdizimi Farkları

ps komutunun iki farklı sözdizimi vardır ve bu durum yeni başlayanları sık sık karıştırır.

Unix stili: Tire işareti ile kullanılır: ps -ef

BSD stili: Tire işareti olmadan kullanılır: ps aux

Her iki stil de aynı sonucu verir ama Linux’ta her ikisi de desteklenir. Benim tercihim ps aux veya ps -ef şeklindedir çünkü ikisi de kapsamlı çıktı üretir.

# En temel kullanım - sadece kendi terminalindeki süreçleri gösterir
ps

# BSD stiliyle tüm süreçler
ps aux

# Unix stiliyle tüm süreçler
ps -ef

Sade ps yazdığında yalnızca kendi oturumuna ait süreçleri görürsün. Genellikle bu işine yaramaz, sistemi izlemek için daha geniş bir görünüm istersin.

ps aux Çıktısını Anlamak

ps aux çıktısındaki sütunlar şunlardır:

  • USER: Süreci başlatan kullanıcı
  • PID: Süreç ID numarası
  • %CPU: CPU kullanım yüzdesi
  • %MEM: Bellek kullanım yüzdesi
  • VSZ: Sanal bellek kullanımı (KB)
  • RSS: Fiziksel bellek kullanımı (KB)
  • TTY: Hangi terminal üzerinden çalıştığı
  • STAT: Süreç durumu
  • START: Başlama zamanı
  • TIME: Toplam CPU süresi
  • COMMAND: Komutun kendisi

STAT sütunu özellikle önemlidir:

  • R: Çalışıyor (Running)
  • S: Uyuyor (Sleeping), ama uyandırılabilir
  • D: Kesintisiz uyuyor (genellikle I/O bekliyor)
  • Z: Zombie süreç
  • T: Durdurulmuş (stopped)
  • s: Oturum lideri
  • +: Foreground süreç
  • l: Çok thread’li

Sık Kullandığım Parametreler

  • a: Tüm kullanıcıların süreçlerini göster (BSD)
  • u: Kullanıcı odaklı çıktı formatı (BSD)
  • x: Terminal olmayan süreçleri de dahil et (BSD)
  • -e: Tüm süreçleri göster (Unix)
  • -f: Tam format (Unix)
  • -u [kullanici]: Belirli kullanıcının süreçleri
  • -p [PID]: Belirli PID için bilgi
  • –sort: Çıktıyı sırala
  • -o: Özel çıktı formatı tanımla
  • –forest: Süreç ağacını göster
  • -H: Hiyerarşik görünüm

Filtreleme: grep ile Kombinasyon

Gerçek gücü burada başlıyor. Belirli bir uygulamanın çalışıp çalışmadığını kontrol etmek istiyorsun diyelim:

# Nginx çalışıyor mu?
ps aux | grep nginx

# Ama bu çıktıda grep'in kendisi de görünür, bunu engellemek için:
ps aux | grep [n]ginx

# Veya grep -v kullan
ps aux | grep nginx | grep -v grep

Köşeli parantez hilesini ([n]ginx) öğrendiğimde küçük bir “aha!” anı yaşamıştım. Çünkü [n]ginx şeklinde grep çalıştırdığında, grep kendi kendini aramaz, zira process listesinde [n]ginx değil grep [n]ginx görünür ve bu pattern kendi kendine uymaz.

Belirli Bir Kullanıcının Süreçlerini Listeleme

Paylaşımlı sunucularda çok kullanıcı olabilir. Kimin ne çalıştırdığını görmek önemlidir:

# www-data kullanıcısının tüm süreçleri
ps -u www-data

# Daha detaylı çıktı
ps -fu www-data

# Birden fazla kullanıcı için
ps -u deploy,www-data,postgres

Bir keresinde paylaşımlı hosting ortamında bir müşteri hesabından anormal CPU kullanımı vardı. ps -fu musterihesabi komutuyla hemen görüntüledim ve o kullanıcının crypto mining scripti çalıştırdığını fark ettim. Direkt ps çıktısı durumu anında ortaya koydu.

Süreç Ağacını Görüntüleme

Parent-child ilişkisini anlamak debug sürecinde kritiktir:

# Süreç ağacını göster
ps aux --forest

# Sadece belirli bir sürecin çocuklarını görmek için
ps --ppid 1234

# Unix stiliyle hiyerarşik görünüm
ps -ejH

# pstree ile daha güzel görünüm (ps değil ama ilgili)
# ps ile: 
ps -ef --forest | grep apache
# Örnek: PHP-FPM worker'larını parent ile birlikte görmek
ps aux --forest | grep php-fpm

Bu komut şöyle bir çıktı verir:

root     12345  0.0  0.1  php-fpm: master process
www-data 12346  0.0  0.2   _ php-fpm: pool www
www-data 12347  0.0  0.2   _ php-fpm: pool www
www-data 12348  0.0  0.2   _ php-fpm: pool www

Master process ve worker’lar arasındaki ilişkiyi görmek, özellikle bir worker’ın asılı kaldığında çok işe yarar.

Özel Çıktı Formatı Oluşturma

-o parametresiyle sadece ihtiyacın olan sütunları seçebilirsin. Bu özellikle betik yazarken çok değerlidir:

# Sadece PID ve komut adı
ps -eo pid,comm

# PID, kullanıcı, CPU, bellek ve komut
ps -eo pid,user,%cpu,%mem,comm

# Daha uzun komut satırını görmek için cmd kullan (comm yerine)
ps -eo pid,user,%cpu,%mem,cmd

# Başlatma zamanı ile birlikte
ps -eo pid,user,lstart,cmd

comm sütunu sadece binary adını verir, cmd ise tüm argümanları gösterir. Hangisini seçeceğin duruma göre değişir. Bir Java uygulamasını izliyorsan cmd şart, aksi halde hepsini java olarak görürsün.

Sıralama: En Çok Kaynak Tüketeni Bulmak

Sunucu yavaşladı, kim yiyor kaynakları? Hemen bak:

# CPU kullanımına göre sırala (azalan)
ps aux --sort=-%cpu | head -10

# Bellek kullanımına göre sırala (azalan)
ps aux --sort=-%mem | head -10

# Her ikisini birden görmek istersen awk ile
ps aux --sort=-%cpu | awk 'NR<=11{print}'
# Gerçek dünya senaryosu: Hangi süreçler en fazla bellek tüketiyor?
ps -eo pid,user,%mem,rss,cmd --sort=-%mem | head -15

Bu komutu bir sunucuda bellek sıkıntısı başladığında çalıştırıyorum. rss sütunu gerçek fiziksel bellek kullanımını gösterir ve çoğu zaman suçluyu hemen ortaya koyar.

PID ile Belirli Bir Süreci İzleme

Bir sürecin PID’ini biliyorsun ve detaylarına bakmak istiyorsun:

# Tek bir PID için
ps -p 1234

# Birden fazla PID için
ps -p 1234,5678,9012

# Detaylı çıktı
ps -fp 1234

# O sürecin açık dosyalarını da görmek istersen (lsof ile kombinasyon)
ps -fp 1234 && lsof -p 1234

Mesela bir uygulama beklenmedik şekilde belirli bir PID’de takılıp kalmışsa ve o process’in ne yaptığını anlamak istiyorsan bu kombinasyon işine yarar.

Zombie Süreçleri Bulma

Zombie süreçler sistem kaynağı tüketmez ama PID tablosunu tıkayabilir ve bazen altta yatan bir probleme işaret eder:

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

# Daha temiz bir yol
ps -eo pid,ppid,stat,comm | grep -w Z

# Kaç tane zombie var?
ps aux | grep -c ' Z '

Zombie süreç gördüğünde paniklemene gerek yok. Önce parent process’i bul:

# Zombie'nin parent'ını bul (PPID kolonuna bak)
ps -eo pid,ppid,stat,comm | awk '$3~/^Z/{print $0}'

Parent process o zombie’yi “toplamıyorsa” (wait() çağrısı yapmıyorsa) bu bir uygulama hatasına işaret eder.

Pratik Senaryolar

Senaryo 1: Uygulama Çalışıyor mu Diye Kontrol Eden Script

Monitoring ve restart scriptleri yazarken ps çıktısını kullanmak çok yaygındır:

#!/bin/bash
# Belirli bir servisin çalışıp çalışmadığını kontrol et

SERVICE="nginx"

if ps aux | grep -q [n]ginx; then
    echo "$SERVICE çalışıyor."
    PID=$(ps aux | grep [n]ginx | awk '{print $2}' | head -1)
    echo "Ana PID: $PID"
else
    echo "$SERVICE çalışmıyor! Başlatılıyor..."
    systemctl start nginx
fi

Bu tür scriptler cron’a eklendiğinde basit bir uptime monitoring sistemi oluşturabilirsin. Tabii gerçek production ortamında daha sağlam araçlar (monit, supervisord) kullanmanı öneririm, ama temel konsepti anlamak için bu yaklaşım gayet iyi.

Senaryo 2: Belirli Bir Port’ta Çalışan Süreci Bulma

# 8080 portunu dinleyen süreci bul
# Önce ss veya netstat ile PID'i bul
ss -tlnp | grep 8080

# Çıktıdan aldığın PID ile ps'e sor
ps -fp $(ss -tlnp | grep ':8080' | awk '{print $6}' | cut -d',' -f2 | cut -d'=' -f2)

Senaryo 3: Uzun Süredir Çalışan Süreçleri Bulma

Bazen asılı kalan veya beklenenden uzun süredir çalışan süreçleri tespit etmen gerekir:

# Başlama zamanına göre sırala (en eskiler üstte)
ps -eo pid,user,lstart,etime,cmd --sort=start_time | head -20

# 24 saatten uzun süredir çalışan süreçler (etime formatı: DD-HH:MM:SS)
ps -eo pid,user,etime,cmd | awk '$3 ~ /-/ {print}'

etime sütunu sürecin ne kadar süredir çalıştığını gösterir. Tire işareti göründüğünde bu 1 günden fazla demektir.

Senaryo 4: Yüksek CPU Tüketen Süreci Öldürme

# En fazla CPU tüketen 5 süreci bul
ps aux --sort=-%cpu | head -6

# Belirli bir sürecin PID'ini al ve öldür
PROBLEM_PID=$(ps aux --sort=-%cpu | awk 'NR==2{print $2}')
echo "En fazla CPU tüketen süreç: $PROBLEM_PID"

# Önce nazikçe sor
kill -15 $PROBLEM_PID

# Dinlemezse zorla
sleep 5
kill -9 $PROBLEM_PID

Bunu direkt bir one-liner olarak kullanmak risklidir, o yüzden her zaman önce PID’i echo ile doğrula, sonra kill et.

ps ve watch Kombinasyonu

ps statik bir anlık görüntü sunar ama watch ile onu dinamik hale getirebilirsin:

# Her 2 saniyede CPU kullanımını güncelle
watch -n 2 'ps aux --sort=-%cpu | head -10'

# Belirli bir süreci takip et
watch -n 1 'ps -fp 1234'

# Nginx worker sayısını izle
watch -n 5 'ps aux | grep [n]ginx | wc -l'

top kadar gösterişli değil ama belirli bir konuya odaklanmış izleme için çok kullanışlı. Özellikle bir deployment sırasında servis worker sayısını takip etmek için bu yöntemi sık kullanıyorum.

Uzak Sunucuda Hızlı Durum Kontrolü

SSH ile bağlandığında ilk ne yaparsın? Ben genellikle şu bloğu çalıştırırım:

# Hızlı sistem durumu kontrolü
echo "=== En fazla CPU tüketenler ===" && 
ps aux --sort=-%cpu | head -6 && 
echo "" && 
echo "=== En fazla bellek tüketenler ===" && 
ps aux --sort=-%mem | head -6 && 
echo "" && 
echo "=== Zombie süreçler ===" && 
ps aux | grep ' Z '

Bu bloğu .bashrc içinde bir alias olarak tanımlamak çok işlevsel olabilir:

# .bashrc veya .bash_aliases içine ekle
alias pstop='ps aux --sort=-%cpu | head -11'
alias psmem='ps aux --sort=-%mem | head -11'
alias pszombie='ps -eo pid,ppid,stat,comm | grep -w Z'

/proc ile ps İlişkisi

ps aslında sahne arkasında /proc dosya sistemini okur. Bunu anlamak, ps’in neden her zaman doğru bilgi vermediğini veya bazı durumlarda neden /proc/[PID]/ dizinine direkt bakmak gerektiğini açıklar.

# PID 1234 için aynı bilgilere direkt proc'tan bak
cat /proc/1234/status
cat /proc/1234/cmdline | tr '' ' '

# ps ile doğrula
ps -fp 1234

Bu ilişkiyi bilmek, özellikle konteyner ortamlarında veya bazı süreçlerin ps’te görünmediği durumlarda işine yarar.

Procps Sürüm Farklılıkları

Dikkat etmen gereken bir nokta: ps komutunun davranışı farklı Linux dağıtımlarında ve procps-ng sürümlerine göre değişebilir. Özellikle --sort parametresinin bazı eski sürümlerde çalışmaması veya lstart sütununun bazı minimal kurulumda bulunmaması gibi durumlarla karşılaşabilirsin.

# ps sürümünü kontrol et
ps --version

# Hangi procps paketini kullanıyorsun?
dpkg -l procps    # Debian/Ubuntu
rpm -qi procps-ng # RHEL/CentOS

Farklı sunucularda farklı davranışlar görüyorsan önce bu sürüm farkını kontrol et.

Güvenlik Açısından ps

ps aux tüm kullanıcıların tüm süreçlerini gösterir. Bu, komut satırında geçirilen argümanları da gösterir. Biri şifreyi argüman olarak geçirirse:

# Kötü pratik - şifre komut satırında görünür
mysql -u root -pGizliSifre123

# ps aux çıktısında bu görünür:
# root 9999 0.0 0.0 mysql -u root -pGizliSifre123

Bu durum ciddi bir güvenlik açığıdır. Şifrelerin komut satırı argümanı olarak değil, ortam değişkeni veya config dosyası üzerinden aktarılması gerekir. Bazı yeni Linux çekirdeğinde /proc/[PID]/cmdline erişimi kısıtlanabilir ama standart olarak ps aux herkes tarafından görülebilir.

Sonuç

ps komutu basit görünür ama içinde gerçekten geniş bir dünya var. Temel kullanım olan ps aux ile başlayıp, --forest ile süreç hiyerarşisini görmek, -o ile özel çıktı formatları oluşturmak ve grep, awk, sort gibi araçlarla zincirlemek seni ciddi anlamda güçlendirir.

Benim önerim şu: Bir sonraki sunucu sorununla karşılaştığında önce ps aux --sort=-%cpu | head -10 ve ps aux --sort=-%mem | head -10 çalıştır. Suçluyu çoğunlukla ilk bakışta bulursun. Ardından o süreci daha derin incelemek için PID bazlı sorgular ve süreç ağacı görünümünü kullan.

top ve htop gibi araçlar görsel olarak daha çekici, ama betik yazıyorsan, otomasyona ihtiyaç duyuyorsan ve çıktıyı başka komutlara besliyorsan ps hep birinci tercih olacak. Yıllardır bu böyle, ve yakın gelecekte de değişeceğe benzemiyor.

Yorum yapın