Yazılar

touch Komutu: Dosya Oluşturma ve Zaman Damgası Değiştirme

touch komutu göründüğünden çok daha güçlü bir araç. Sadece boş dosya oluşturmakla kalmıyor, web sunucusu yönetiminde kritik öneme sahip zaman damgası işlemlerini de üstleniyor. Bu yazıda touch komutunu her yönüyle inceliyoruz.

Sysadmin kariyerinde bir noktada şunu fark ediyorsun: en basit görünen komutlar çoğu zaman en çok işe yarayan komutlar oluyor. touch da tam olarak bu kategoride. “Ne kadar karmaşık olabilir ki, dosya oluşturuyorsun işte” diye düşünebilirsin. Ama web sunucusu yönetimi söz konusu olduğunda bu küçük komut seni ciddi baş ağrılarından kurtarabilir, ya da yanlış kullanırsan ciddi sorunlara davet edebilir. Hadi konuya girelim.

touch Komutu Nedir ve Ne Yapar?

touch, temel olarak iki işi yapan bir komut. Birincisi, var olmayan bir dosyayı oluşturur. İkincisi, var olan bir dosyanın erişim (access) ve değiştirme (modification) zaman damgalarını günceller. Çoğu insan sadece birinci kullanımı bilir ama asıl güç ikincisinde.

Man page’e baktığında seni karşılayan tanım şudur: “touch — change file timestamps”. Dosya oluşturmak aslında bir yan etki. Eğer belirttiğin dosya yoksa, touch onu oluşturur. Varsa, sadece zaman damgasını günceller. Bu ayrımı aklında tutmak önemli.

Temel Kullanım: Dosya Oluşturma

En basit kullanımıyla başlayalım. Web sunucusu ortamında sıklıkla boş dosya oluşturman gerekir. Maintenance sayfaları, lock dosyaları, pid dosyaları veya sadece test amaçlı placeholder dosyalar…

# Tek dosya oluşturma
touch maintenance.html

# Birden fazla dosyayı tek seferde oluşturma
touch index.html style.css app.js

# Belirli bir dizinde dosya oluşturma
touch /var/www/html/.maintenance

# Birden fazla log dosyası oluşturma
touch /var/log/myapp/{error,access,debug}.log

Süslü parantez kullanımına dikkat et. Bu bash’ın brace expansion özelliği ve touch ile birleşince çok kullanışlı bir hal alıyor. Tek komutla birden fazla dosya oluşturabiliyorsun.

Bilgi: touch ile oluşturulan dosya tamamen boştur, 0 byte boyutundadır. İçine bir şey yazmak istiyorsan farklı komutlara ihtiyacın olacak. touch sadece dosyanın var olmasını sağlar.

Zaman Damgaları: Asıl Mesele Burada

Linux’ta her dosyanın üç tür zaman damgası vardır. Bunları bilmeden touch’ı gerçek anlamda kullanamazsın.

Zaman DamgasıKısaltmaNe Zaman Değişir?touch ile Değişir mi?
Access TimeatimeDosya okunduğundaEvet (-a ile)
Modification Timemtimeİçerik değiştiğindeEvet (-m ile)
Change TimectimeMetadata değiştiğindeDolaylı olarak

touch varsayılan olarak hem atime’ı hem de mtime’ı şu anki zamana günceller. ctime ise her zaman otomatik güncellenir çünkü bir şeyleri değiştirdiğinde dosyanın metadata’sı da değişmiş olur.

Mevcut Zaman Damgalarını Görüntüleme

Önce mevcut durumu nasıl göreceğini bilelim. stat komutu bu iş için biçilmiş kaftan:

# Dosyanın tüm zaman damgalarını göster
stat /var/www/html/index.html

# Örnek çıktı:
#   File: /var/www/html/index.html
#   Size: 10674     Blocks: 24         IO Block: 4096   regular file
# Device: fd00h/64768d    Inode: 785432      Links: 1
# Access: (0644/-rw-r--r--)  Uid: (   33/www-data)   Gid: (   33/www-data)
# Access: 2024-01-15 14:23:45.123456789 +0300
# Modify: 2024-01-14 09:15:22.987654321 +0300
# Change: 2024-01-14 09:15:22.987654321 +0300

# Sadece modification time'ı görmek için
date -r /var/www/html/index.html

touch Seçenekleri ve Parametreler

Komutun seçeneklerine geçelim. Bunları bilmeden touch’ın yarısını kullanmıyorsun demektir.

# Sadece access time'ı güncelle (-a)
touch -a /var/www/html/index.html

# Sadece modification time'ı güncelle (-m)
touch -m /var/www/html/index.html

# Dosya yoksa oluşturma, sadece varsa güncelle (-c veya --no-create)
touch -c /var/www/html/opsiyonel-dosya.html

# Belirli bir zaman damgası belirt (-t)
# Format: [[CC]YY]MMDDhhmm[.ss]
touch -t 202401150930.00 /var/www/html/index.html

# Belirli bir tarihi string olarak belirt (-d)
touch -d "2024-01-15 09:30:00" /var/www/html/index.html
touch -d "yesterday" /var/www/html/index.html
touch -d "2 hours ago" /var/www/html/index.html
touch -d "next monday" /var/www/html/index.html

# Başka bir dosyanın zaman damgasını kopyala (-r)
touch -r /var/www/html/referans.html /var/www/html/hedef.html

Ipucu: -d seçeneği oldukça esnek bir format kabul ediyor. “yesterday”, “last week”, “2 hours ago” gibi insan okunabilir ifadeler de çalışıyor. Bu özelliği özellikle test senaryolarında çok işe yarar buluyorum.

Web Sunucusu Senaryolarında Gerçek Dünya Kullanımı

Teoriden pratiğe geçelim. Web sunucusu yönetiminde touch’ı en çok nerede ve nasıl kullanıyorsun, bunlara bakalım.

1. Maintenance Modu Lock Dosyası

Laravel, Symfony gibi PHP framework’leri maintenance modunu genellikle bir dosyanın varlığına göre kontrol eder. touch burada biçilmiş kaftan:

# Laravel maintenance modunu aktif et (manuel yöntem)
touch /var/www/html/myapp/storage/framework/down

# Birden fazla sanal sunucu için aynı anda maintenance aç
for site in site1 site2 site3; do
    touch /var/www/html/${site}/storage/framework/down
    echo "${site} maintenance moduna alindi"
done

# Maintenance bitti, lock dosyasını kaldır
rm /var/www/html/myapp/storage/framework/down

# Nginx için maintenance flag dosyası
touch /var/run/nginx-maintenance
# nginx.conf'ta bu dosyanın varlığını kontrol edip 503 döndürebilirsin

2. PHP-FPM ve Nginx Cache Yönetimi

Web sunucusu caching mekanizmaları zaman damgalarına büyük önem verir. mtime değiştiğinde cache geçersiz sayılır. Bu davranışı touch ile kontrol edebilirsin:

# PHP-FPM'i yeniden başlatmadan opcache'i temizlemek için
# (bazı yapılandırmalarda dosya değişikliği opcache invalidation'ı tetikler)
touch /var/www/html/myapp/public/index.php

# Nginx fastcgi_cache'i belirli dosyalar için geçersiz kıl
# cache key dosyasının timestamp'ini güncelle
touch /var/cache/nginx/cache-purge-trigger

# Tüm PHP dosyalarının mtime'ını güncelle (dikkatli kullan!)
find /var/www/html/myapp -name "*.php" -exec touch {} ;

# Sadece belirli bir dizindeki dosyaları güncelle
find /var/www/html/myapp/app -name "*.php" -maxdepth 2 -exec touch {} ;

Uyari: find ile birlikte toplu touch kullanımı çok sayıda dosyayı etkiler. Production ortamında bunu yapmadan önce tam olarak ne yapacağını bildiğinden emin ol. Yanlış dizinde çalıştırırsan beklenmedik cache invalidation sorunlarıyla karşılaşabilirsin.

3. Log Dosyası Yönetimi

Yeni bir web uygulaması deploy ederken log dosyalarının önceden oluşturulmuş ve doğru izinlerle hazır olması gerekir. Uygulama başladığında log dosyası yoksa hata verebilir:

# Uygulama log dosyalarını oluştur ve izinleri ayarla
LOG_DIR="/var/log/mywebapp"

# Dizini oluştur
mkdir -p ${LOG_DIR}

# Log dosyalarını oluştur
touch ${LOG_DIR}/error.log
touch ${LOG_DIR}/access.log
touch ${LOG_DIR}/slow-query.log

# Sahipliği ve izinleri ayarla
chown -R www-data:www-data ${LOG_DIR}
chmod 640 ${LOG_DIR}/*.log

# Doğrulama
ls -la ${LOG_DIR}/

4. Deployment Script’lerinde touch Kullanımı

CI/CD pipeline’larında ve deployment script’lerinde touch oldukça sık kullanılır. İşte tipik bir deployment senaryosu:

#!/bin/bash
# deploy.sh - Basit web uygulaması deployment scripti

APP_DIR="/var/www/html/myapp"
DEPLOY_TIME=$(date +%Y%m%d_%H%M%S)

echo "[${DEPLOY_TIME}] Deployment basliyor..."

# 1. Maintenance modunu aktif et
touch ${APP_DIR}/storage/framework/down
echo "Maintenance modu aktif"

# 2. Yeni kodları cek (git, rsync vb.)
git -C ${APP_DIR} pull origin main

# 3. Config dosyalarının varlığını garantile
touch ${APP_DIR}/.env
touch ${APP_DIR}/storage/logs/laravel.log

# 4. Cache dosyalarının timestamp'ini güncelle
# Bu sayede PHP opcache yeni kodu alacak
find ${APP_DIR}/bootstrap/cache -name "*.php" -exec touch {} ;

# 5. Deployment zaman damgasını kaydet
touch ${APP_DIR}/storage/deployed_at
echo "Son deployment: ${DEPLOY_TIME}" > ${APP_DIR}/storage/deployed_at

# 6. Maintenance modunu kapat
rm -f ${APP_DIR}/storage/framework/down
echo "Deployment tamamlandi. Maintenance modu kapatildi."

Zaman Damgasını Taklit Etmek: Dikkatli Ol

touch’ın güçlü özelliklerinden biri geçmişe veya geleceğe tarih atayabilmek. Bu özellik bazen meşru ihtiyaçlar için kullanılır, örneğin bir dosyayı eski bir yedeğe senkronize etmek. Ama aynı zamanda kötüye kullanılabilecek bir özellik.

# Dosyayı belirli bir tarihe "götür"
touch -d "2023-06-15 12:00:00" /var/www/html/eski-icerik.html

# Bir dosyanın zaman damgasını başka bir dosyayla eşitle
# Örnek: yedekten gelen dosyayla production'ı senkronize et
touch -r /backup/2024/index.html /var/www/html/index.html

# Belirli bir formatta zaman damgası ata
# Format: CCYYMMDDhhmm.ss
touch -t 202406151200.00 /var/www/html/special-file.html

Uyari: Dosya zaman damgalarını manipüle etmek güvenlik loglarını ve audit trail’leri bozabilir. Forenzik inceleme gerektiren sistemlerde ya da compliance zorunluluğu olan ortamlarda zaman damgasını geriye almak ciddi sorunlara yol açabilir. Bu özelliği ne zaman ve neden kullandığını belgele.

Atomik Dosya Oluşturma ve Race Condition

Yüksek trafikli web sunucularında birden fazla process aynı anda çalışıyor olabilir. touch’ın atomik olmayan bir operasyon olduğunu bilmek gerekiyor. Yani iki process aynı anda aynı dosyayı oluşturmaya çalışırsa race condition oluşabilir. Lock mekanizması için touch’a güvenmemelisin.

Bunun yerine gerçek lock dosyası oluşturma için daha güvenilir yöntemler var:

# touch ile basit varlık kontrolü (lock için YETERSİZ)
if [ ! -f /tmp/myapp.lock ]; then
    touch /tmp/myapp.lock  # Race condition riski var!
    # işlemler...
    rm /tmp/myapp.lock
fi

# Daha güvenilir lock için flock kullan
flock -n /tmp/myapp.lock -c "bash /var/www/html/myapp/cron/cleanup.sh"

# Ya da mkdir kullan (atomik operasyon)
if mkdir /tmp/myapp.lockdir 2>/dev/null; then
    echo $$ > /tmp/myapp.lockdir/pid
    # işlemler...
    rm -rf /tmp/myapp.lockdir
else
    echo "Baska bir process calisıyor, cikiliyor."
    exit 1
fi

Bilgi: mkdir operasyonu atomiktir çünkü işletim sistemi seviyesinde tek bir sistem çağrısıyla gerçekleşir. Bu yüzden lock mekanizması olarak mkdir, touch’a göre çok daha güvenilirdir. Bu küçük ama önemli bir fark.

Otomatik Görevlerde touch Kullanımı

Cron job’larında ve otomatik bakım scriptlerinde touch sıklıkla kullanılır. İşte birkaç pratik örnek:

# Crontab'dan çalışacak bir bakım scripti
#!/bin/bash
# /usr/local/bin/webserver-health-check.sh

HEALTH_FILE="/var/run/webserver-health"
LOG_FILE="/var/log/health-check.log"

# Nginx çalışıyor mu kontrol et
if systemctl is-active --quiet nginx; then
    # Sağlık dosyasının timestamp'ini güncelle
    # Monitoring sistemi bu dosyanın tarihini izleyebilir
    touch ${HEALTH_FILE}
    echo "$(date): Nginx sagliklı" >> ${LOG_FILE}
else
    # Dosyayı silme veya güncelleme, monitoring alarm verir
    echo "$(date): Nginx calısmiyor! Alarm!" >> ${LOG_FILE}
    # Alert gönder
    /usr/local/bin/send-alert.sh "Nginx down" "critical"
fi

# Log dosyasını rotasyona hazırla
# Son güncelleme üzerinden 7 gün geçmişse sıfırla
find ${LOG_FILE} -mtime +7 -exec sh -c 'cat /dev/null > {}' ;

Sık Yapılan Hatalar

Yıllar içinde gördüğüm ve bizzat yaptığım bazı hataları paylaşayım:

  • Var olan bir dosyayı touch’lamak içeriğini silmez ama aklından çıkarabilir. Dosyayı truncate etmek istiyorsan farklı bir yöntem kullanmalısın.
  • touch için hedef dizin mevcut olmalıdır. Dizin yoksa touch hata verir. Önce mkdir -p ile dizini oluştur.
  • touch’ın başarıyla çalışması için ilgili dizinde write iznine ihtiyacın var. Web sunucusu dizinlerinde root veya www-data olarak çalışman gerekebilir.
  • Symlink’leri touch’larken dikkatli ol. Varsayılan olarak touch symlink’in kendisini değil, işaret ettiği dosyayı günceller. Symlink’in kendisini güncellemek için -h veya –no-dereference seçeneğini kullan.
  • NFS mount edilmiş dosya sistemlerinde zaman senkronizasyon sorunları olabilir. touch -t ile kesin bir zaman belirtmek bazen daha güvenlidir.

Hızlı Referans Tablosu

SecenekUzun HaliAçıklamaÖrnek
-a–time=atimeSadece access time güncelletouch -a dosya.txt
-m–time=mtimeSadece modification time güncelletouch -m dosya.txt
-c–no-createDosya yoksa oluşturmatouch -c dosya.txt
-d–date=STRINGString ile tarih belirttouch -d “yesterday” dosya.txt
-tTimestamp formatıyla tarih belirttouch -t 202401150930 dosya.txt
-r–reference=DOSYAReferans dosyanın zamanını kullantouch -r ref.txt hedef.txt
-h–no-dereferenceSymlink’in kendisini güncelletouch -h link.txt

Özet

touch komutu basit görünür ama web sunucusu yönetiminde düşündüğünden çok daha fazla yerde karşına çıkar. Maintenance lock dosyaları, cache invalidation, log dosyası hazırlama, deployment scriptleri… Bunların hepsi touch’ın doğal habitatı. Özellikle zaman damgası manipülasyonu özelliğini ve -r, -d seçeneklerini bilmek seni ortalama kullanıcıdan bir adım öne çıkarır.

En önemli nokta şu: touch’ı bir lock mekanizması olarak kullanma. Race condition’lara açık. Bunun için flock veya mkdir kullan. Geri kalan her şeyde touch oldukça güvenilir ve hızlı bir araç.

Sonraki Adımlar

touch’ı sindirdiysen, birlikte çok güzel çalıştığı araçlara da bakmanı öneririm:

  • stat komutu: Dosya zaman damgalarını ve metadata’yı detaylı görüntülemek için
  • find komutu: Zaman damgasına göre dosya aramak için (-mtime, -atime, -newer seçenekleri)
  • flock komutu: Gerçek dosya kilitleme mekanizması için
  • inotifywait: Dosya değişikliklerini gerçek zamanlı izlemek için
  • logrotate: Log dosyası rotasyonunu otomatikleştirmek için

Bu araçları birlikte öğrenmek, web sunucusu yönetiminde dosya operasyonlarını çok daha verimli yapmanı sağlayacak. Her biri ayrı bir yazı konusu, sırasıyla ele alacağız.

rm Komutu ile Dosya Silme: Web Sunucusunda Güvenli Kullanım Rehberi

Linux’ta rm komutu basit görünür ama yanlış kullanıldığında web sunucunu dakikalar içinde çökertebilir. Bu yazıda rm’nin tüm inceliklerini, güvenli kullanım yöntemlerini ve gerçek sunucu senaryolarını ele alıyoruz.

Linux dünyasında bazı komutlar vardır ki görünürde masum, ama elinde patlayacak dinamit gibidir. rm komutu da tam olarak bu kategoriye girer. Web sunucusu yönetiyorsan ve terminale “rm -rf /” yazarsan ne olacağını merak ediyorsan, cevap şu: bir daha o sunucuyu göremezsin. Abartmıyorum.

Ama paniklemene de gerek yok. rm komutu doğru anlaşıldığında ve doğru kullanıldığında vazgeçilmez bir araçtır. Eski log dosyalarını temizlemek, geçici upload dosyalarını silmek, eski deployment kalıntılarını ortadan kaldırmak — bunların hepsinde rm kullanırsın. Bu yazıda hem temel kullanımı hem de bir web sunucusu yöneticisi olarak günlük hayatta karşılaşacağın gerçek senaryoları ele alacağız.

rm Komutu Nedir ve Nasıl Çalışır?

rm, “remove” kelimesinin kısaltmasıdır ve Linux/Unix sistemlerde dosya ile dizinleri silmek için kullanılır. Windows’taki Delete tuşundan temel farkı şudur: silinen dosyalar Geri Dönüşüm Kutusu’na gitmez. Silinen dosya gider, noktası.

Teknik olarak konuşmak gerekirse, rm komutu dosyanın kendisini değil, dosya sistemindeki inode bağlantısını siler. Eğer o dosyaya başka hard link yoksa, inode ve veri blokları serbest bırakılır. Bu yüzden bazen özel araçlarla (extundelete, testdisk gibi) silinen dosyaları kurtarmak mümkün olabilir — ama buna güvenerek çalışma, her silme işlemini geri dönüşü olmayan bir işlem olarak gör.

Temel Söz Dizimi

rm komutunun temel kullanımı son derece sade:

rm [seçenekler] [dosya/dizin]

# Tek dosya silmek
rm dosya.txt

# Birden fazla dosya silmek
rm dosya1.txt dosya2.txt dosya3.log

# Belirli bir pattern ile silmek
rm *.log

# Belirli bir dizindeki tüm .tmp dosyalarını silmek
rm /var/www/html/uploads/*.tmp

Bu kadar basit. Ama işte tam burada dikkatli olmak gerekiyor. Yukarıdaki son komuta bak: /var/www/html/uploads dizinindeki tüm .tmp dosyalarını silmek istiyorsun. Eğer yanlışlıkla bir boşluk karakteri koyarsan ya da dizin adını yanlış yazarsan, sonuçlar beklenmedik olabilir.

Önemli Parametreler ve Anlamları

ParametreUzun HaliNe Yapar?
-r–recursiveDizini ve içindeki her şeyi siler
-f–forceVar olmayan dosyalar için hata vermez, onay istemez
-i–interactiveHer silme işleminden önce onay ister
-I–interactive=once3’ten fazla dosya veya -r kullanılıyorsa bir kez onay ister
-v–verboseHer silinen dosyayı ekrana yazar
-d–dirBoş dizinleri siler (rmdir gibi)

Web Sunucusunda Gerçek Kullanım Senaryoları

Teoriyi bir kenara bırakalım ve asıl konuya gelelim: web sunucusu yönetirken rm’yi nerede, nasıl kullanırsın?

Senaryo 1: Eski Log Dosyalarını Temizleme

Nginx veya Apache çalıştırıyorsun ve /var/log dizini dolmaya başladı. Disk dolunca web sunucusu yeni bağlantılara cevap veremez hale gelir. Bu yüzden log rotasyonu ve temizliği kritik önem taşır. Logrotate kullanıyor olsan bile, bazen manuel müdahale gerekir:

# 30 günden eski nginx access log dosyalarını bul ve sil
find /var/log/nginx/ -name "access.log.*" -mtime +30 -exec rm -v {} ;

# 7 günden eski tüm .gz uzantılı sıkıştırılmış logları sil
find /var/log/apache2/ -name "*.gz" -mtime +7 -exec rm -v {} ;

# Silmeden önce ne silineceğini gör (dry-run)
find /var/log/nginx/ -name "*.log.*" -mtime +30 -print

Ipucu: rm’yi doğrudan find ile kullanmadan önce mutlaka -print ile ne silineceğini gör. Bu alışkanlık seni bir gün büyük bir felaketten kurtarabilir.

Senaryo 2: Upload Klasöründeki Geçici Dosyaları Temizleme

PHP tabanlı bir web uygulaması çalıştırıyorsun ve kullanıcılar dosya yüklüyor. Yarım kalan yüklemeler, işlenmeyi bekleyen geçici dosyalar, hatalı upload’lar zamanla birikir. Bunu düzenli olarak temizlemek hem disk alanı hem de güvenlik açısından önemli.

# /var/www/html/uploads dizinindeki 24 saatten eski .tmp dosyalarını sil
find /var/www/html/uploads/ -name "*.tmp" -mtime +1 -exec rm -f {} ;

# Boş dizinleri de temizle
find /var/www/html/uploads/ -type d -empty -exec rm -d {} ;

# İşlem sonrası ne kadar yer açıldığını kontrol et
df -h /var/www/

Senaryo 3: Eski Deployment Dosyalarını Kaldırma

Manuel veya CI/CD ile deployment yapıyorsan, eski versiyonlar birikebilir. Bir WordPress güncellemesinden sonra eski plugin dosyalarını temizlemek ya da manuel olarak yüklediğin eski bir PHP uygulamasının kalıntılarını kaldırmak gerekebilir:

# Eski deployment klasörünü sil (dikkatli ol, önce ls ile kontrol et)
ls -la /var/www/
rm -rf /var/www/app_v1.2.3/

# Aktif deployment sembolik linkini değiştirmeden önce eski versiyonu kaldır
rm -rf /var/www/releases/20231101120000/

# Belirli dosya uzantılarını recursive olarak sil (örn: .bak dosyaları)
find /var/www/html/ -name "*.bak" -type f -delete

Uyari: rm -rf komutunu çalıştırmadan önce mutlaka pwd ile hangi dizinde olduğunu kontrol et ve silmek istediğin yolu tam olarak belirt. Eksik bir slash, yanlış bir dizin adı büyük sorunlara yol açabilir.

rm -rf: Güçlü Ama Tehlikeli

Bu parametre kombinasyonunu ayrıca ele almak istiyorum çünkü en çok kullanılan ve en tehlikeli olanı bu. -r recursive (alt dizinlerle birlikte), -f ise force (onay istemeden, hata görmezden gelerek) demek. İkisini birleştirdiğinde önüne gelen her şeyi süpüren bir komut elde edersin.

Gerçek bir hikaye anlatayım: Bir sysadmin, eski bir web uygulamasını kaldırmak için şu komutu çalıştırmak istiyor: rm -rf /var/www/eski-uygulama. Ama yanlışlıkla araya bir boşluk giriyor: rm -rf /var/www/ eski-uygulama. Bu durumda sistem önce /var/www/ dizinini, ardından eski-uygulama adlı dosyayı silmeye çalışır. /var/www/ dizininin tüm içeriği gider.

Uyari: rm -rf komutunu root kullanıcısı olarak çalıştırırken son derece dikkatli ol. Modern Linux sistemleri rm -rf / komutunu –no-preserve-root parametresi olmadan çalıştırmana izin vermez, ama bu seni her şeyden korumaz. /var/www, /etc, /home gibi kritik dizinlerde rm -rf kullanmadan önce iki kez düşün.

Güvenli rm Kullanımı için Pratik Yöntemler

1. -i Parametresi ile Onaylı Silme

Eğer kritik bir dizinde çalışıyorsan ve tam olarak emin değilsen, -i parametresini kullan. Her dosya için senden onay ister:

# Her silme için onay iste
rm -i *.log

# Recursive silme için bir kez onay iste (-I büyük harf)
rm -rI /var/www/eski-klasor/

# Önce ne silineceğini listele, sonra karar ver
ls -la /var/www/html/cache/
rm -riv /var/www/html/cache/

2. Alias ile Güvenli rm Tanımla

Bazı sysadminler rm komutunu doğrudan çağırmak yerine, her zaman onaylı çalışması için alias tanımlar. Bu özellikle yeni başlayan ekip üyeleri için iyi bir pratiktir:

# ~/.bashrc veya ~/.bash_aliases dosyasına ekle
alias rm='rm -i'

# Alias'ı aktif et
source ~/.bashrc

# Eğer bir kez onaysız çalıştırmak istersen
rm -rf /gecici/klasor/
# veya
command rm -rf /gecici/klasor/

Bilgi: Alias tanımladıktan sonra rm komutunun her zaman -i ile çalışacağını unutma. Script’lerin içinde rm kullanıyorsan, orada da bu davranışı dikkate alman gerekir. Script’lerde genellikle rm veya command rm kullanmak daha güvenlidir.

3. trash-cli: Geri Dönüşüm Kutulu rm Alternatifi

Eğer silme işlemlerinde biraz güvenlik ağı istiyorsan, trash-cli aracını kullanabilirsin. Bu araç dosyaları direkt silmek yerine önce bir çöp klasörüne taşır:

# trash-cli kur (Debian/Ubuntu)
apt install trash-cli

# Dosyayı çöpe gönder
trash-put /var/www/html/gereksiz-dosya.php

# Çöp kutusunu listele
trash-list

# Çöp kutusunu boşalt
trash-empty

# Yanlış sildiysen kurtar
trash-restore

Production sunucularda trash-cli kullanmak tartışmalı bir konu. Disk dolma riskini artırır, ama kritik dosyaların yanlışlıkla silinmesi riskini azaltır. Ekibinin deneyim seviyesine göre karar ver.

Web Sunucusunda Sık Yapılan Hatalar

Yıllar içinde gördüğüm, işittiğim ve ne yazık ki zaman zaman yaşadığım hataları listeleyelim:

  • Dizin değişkeninin boş olması: rm -rf $APP_DIR/ komutunda APP_DIR değişkeni boşsa rm -rf / çalışır
  • Wildcard’ı yanlış kullanmak: rm *.php gibi bir komut mevcut dizindeki tüm PHP dosyalarını siler, hangi dizinde olduğundan emin ol
  • Sembolik linklerin hedefini silmek: rm -rf ile sembolik bir dizini silmeye çalışırken hedef dizini de silebilirsin
  • root olarak çalışırken dikkatsiz olmak: sudo ile çalışırken sistem dosyalarını silmek çok kolaydır
  • Production ve test sunucularını karıştırmak: Birden fazla terminal penceresi açık tutup yanlış pencerede komut çalıştırmak

Bash Script’lerinde rm Kullanımı

Otomatik temizlik script’leri yazarken rm’yi kullanmak kaçınılmaz. Ama script içinde rm kullanırken daha da dikkatli olmak gerekiyor, çünkü bir hata tüm sistemde otomatik olarak çalışabilir.

#!/bin/bash
# Güvenli temizlik scripti örneği

set -euo pipefail  # Hata durumunda dur, tanımsız değişkende dur

# Değişkenleri tanımla
WEB_ROOT="/var/www/html"
LOG_DIR="/var/log/nginx"
MAX_AGE_DAYS=30

# Kritik kontrol: değişken boş mu?
if [ -z "$WEB_ROOT" ] || [ -z "$LOG_DIR" ]; then
    echo "HATA: Dizin değişkenleri boş olamaz!"
    exit 1
fi

# Dizin var mı kontrol et
if [ ! -d "$WEB_ROOT/cache" ]; then
    echo "Cache dizini bulunamadı, atlanıyor."
else
    echo "Cache temizleniyor..."
    find "$WEB_ROOT/cache" -type f -mtime +1 -delete
    echo "Cache temizlendi."
fi

# Eski logları temizle
echo "$MAX_AGE_DAYS günden eski loglar temizleniyor..."
find "$LOG_DIR" -name "*.gz" -mtime +$MAX_AGE_DAYS -exec rm -v {} ;

echo "Temizlik tamamlandi."
df -h $WEB_ROOT $LOG_DIR

Ipucu: Script’lerin başına set -euo pipefail eklemek iyi bir alışkanlıktır. -e herhangi bir komut hata verirse script’i durdurur, -u tanımlanmamış değişkeni kullanmaya çalışırsan hata verir, -o pipefail ise pipeline’daki hataları yakalar. Bu üç ayar, rm içeren otomatik script’lerde kritik öneme sahiptir.

Silinen Dosyaları Kurtarma Girişimi

Teorik olarak ele alalım: yanlışlıkla bir dosyayı sildiysen ne yaparsın? Önce paniği bırak, sonra adım adım düşün.

  • Dosya hala açık bir process tarafından kullanılıyorsa /proc/[pid]/fd/ üzerinden kurtarılabilir
  • ext4 dosya sisteminde testdisk veya extundelete araçlarıyla kurtarma denenebilir
  • Disk üzerine yeni yazma yapılmadan önce ne kadar hızlı müdahale edersen o kadar iyi
  • En güvenli çözüm her zaman yedeğe dönmektir — backupsuz çalışma
# Açık dosya tanımlayıcılarını kontrol et
# Silinmiş ama hala açık olan dosyaları gösterir
lsof | grep deleted

# Eğer process bulunursa, içeriği kurtar
# Örnek: PID 1234, fd 3 numaralı dosya tanımlayıcısı
cat /proc/1234/fd/3 > /tmp/kurtarildi.txt

# Dosya sistemi durumunu kontrol et (unmount gerekir)
# extundelete sadece unmount edilmiş partition üzerinde çalışır
extundelete /dev/sda1 --restore-all

Uyari: Silme işlemi sonrası kurtarma denemesi yaparken hedef partition’a asla yeni veri yazma. Kurtarmayı farklı bir disk üzerine yap. Her yeni yazma işlemi silinen verinin üzerine yazabilir ve kalıcı kayba yol açar.

rm ve Web Sunucusu Güvenliği

Web sunucusu yönetirken rm komutunu güvenlik bağlamında da düşünmek gerekiyor. Saldırganlar web uygulamasına sızdığında bazen dosyaları silmeye çalışabilir ya da zararlı dosyalar bırakabilir. Bu yüzden özellikle kritik web dizinlerinde dosya izinlerini doğru yapılandırmak önemli.

Öte yandan, web uygulamasının kendisinin rm komutunu tetikleyecek shell komutları çalıştırıp çalıştıramayacağını da kontrol altında tutmalısın. PHP uygulamalarında exec(), system(), passthru() gibi fonksiyonların mümkünse devre dışı bırakılması veya en azından kısıtlanması gerekir.

Hizli Referans: rm Komutunun En Sık Kullanılan Formları

KomutNe Yapar?Ne Zaman Kullan?
rm dosya.txtTek dosya silerBelirli bir dosyayı silerken
rm -i dosya.txtOnay sorarak silerKritik dizinlerde çalışırken
rm -f dosya.txtHata vermeden silerScript’lerde, dosya olmayabilir
rm -r dizin/Dizini recursive silerDizin kaldırırken
rm -rf dizin/Onaysız recursive silerEmin olduğunda hızlı temizlikte
rm -v dosya.txtVerbose, işlemi gösterirNe silindiğini takip ederken
rm — -dosya.txtTire ile başlayan dosyayı silerÖzel isimli dosyalarda

Ozet

rm komutu Linux sistemlerde dosya ve dizin silmenin temel yoludur. Basit söz dizimine karşın, özellikle web sunucusu ortamlarında yanlış kullanıldığında ciddi hasara yol açabilir. -r ve -f parametrelerini birlikte kullanırken her zaman dikkatli ol, değişken tabanlı yolları doğrula, ve önemli işlemlerden önce ne sileceğini gözden geçir.

Otomatik script’lerde set -euo pipefail kullanmak, değişken boşluk kontrolü yapmak ve silme öncesi find ile önizleme almak gibi alışkanlıklar, zamanla seni büyük felaketlerden koruyacak. Ayrıca ne kadar deneyimli olursan ol, backup almayı ihmal etme — rm’nin geri alınamaz olduğunu her zaman aklında tut.

Sonraki Adimlar

rm komutuna hakim olduysan, sıradaki adımlar şunlar olabilir:

  • find komutu ile rm’yi birlikte kullanmayı derinlemesine öğren, karmaşık temizlik senaryolarını handle etmek için gerekli
  • rsync ile yedekleme kurarak silme işlemleri öncesi güvenli bir ağ oluştur
  • logrotate yapılandırmasını öğren, log dosyalarını manuel rm ile silmek yerine otomatize et
  • cron job’ları ile düzenli temizlik script’leri yaz ve bunları rm yerine find -delete kombinasyonuyla güvenli hale getir
  • ZFS veya Btrfs gibi snapshot destekleyen dosya sistemlerini araştır, anlık görüntüler sayesinde yanlış silme işlemlerini kolayca geri alabilirsin

mkdir Komutu: Dizin Oluşturma ve Gelişmiş Kullanımı

mkdir komutu göründüğünden çok daha güçlü bir araç. Temel dizin oluşturmanın ötesine geçip, iç içe yapılar, izin yönetimi ve web sunucusu kurulumlarında nasıl kullanacağını bu yazıda adım adım ele alıyoruz.

Sysadmin olarak günde kaç kez mkdir yazıyorsun? Muhtemelen o kadar çok ki artık düşünmeden yapıyorsun. Ama şunu sormam lazım: mkdir‘ın bütün yeteneklerini gerçekten kullanıyor musun? Çoğu kişi bu komutu sadece tek bir dizin oluşturmak için kullanıyor ve olayı orada kapatıyor. Oysa mkdir, doğru kullanıldığında seni onlarca tekrarlayan komuttan kurtarabilir, özellikle web sunucusu kurulumlarında hayat kurtarıcı oluyor.

Bu yazıda mkdir’ı sıfırdan ele alacağız. Temel kullanımdan başlayıp, gelişmiş seçeneklere, gerçek web sunucusu senaryolarına ve sık yapılan hatalara kadar her şeyi konuşacağız. Hazırsan başlayalım.

mkdir Nedir ve Ne İşe Yarar?

mkdir, “make directory” yani “dizin oluştur” anlamına gelir. Linux, macOS ve Windows’ta (hem CMD hem PowerShell üzerinden) kullanılabilen temel bir komuttur. Görevi basit: belirttiğin yerde dizin oluşturmak. Ama bu basit görevin arkasında, işini çok daha verimli yapmanı sağlayacak bir sürü parametre var.

Özellikle web sunucusu yönetimi yapıyorsan — Apache, Nginx, ya da Node.js tabanlı bir şey kuruyorsan — dizin yapılarını doğru ve hızlı oluşturmak kritik. Yanlış izinle oluşturulmuş bir dizin, saat başı dönen bir destek talebi demek. Bunu yaşadın mı biliyorum, herkes yaşadı.

Temel Kullanım

En basit haliyle mkdir şöyle çalışır:

# Tek bir dizin oluştur
mkdir mywebsite

# Tam yol belirterek dizin oluştur
mkdir /var/www/mywebsite

# Aynı anda birden fazla dizin oluştur
mkdir logs uploads cache temp

Bu kadar basit. Ama dikkat et: eğer oluşturmaya çalıştığın dizinin üst dizini yoksa, mkdir hata verir. Mesela /var/www/mywebsite/public oluşturmak istiyorsan ve mywebsite henüz yoksa, komut çakılır. İşte burada -p bayrağı devreye giriyor.

-p Parametresi: En Çok Kullandığın Seçenek Olacak

-p parametresi (“parents” yani üst dizinler) olmayan tüm üst dizinleri otomatik olarak oluşturur. Üstelik zaten var olan bir dizin için hata vermez — bunu özellikle belirtmek istiyorum çünkü script yazarken bu davranış kritik önem taşır.

# İç içe dizin yapısını tek komutla oluştur
mkdir -p /var/www/mywebsite/public_html

# Birden fazla iç içe yapı aynı anda
mkdir -p /var/www/mywebsite/{public_html,logs,ssl,backup}

# Daha karmaşık bir web projesi yapısı
mkdir -p /var/www/myproject/{public,src/{controllers,models,views},config,logs,tests}

Son komuta dikkat et. Süslü parantez genişletmesi (brace expansion) ile tek bir satırda tüm proje iskeletini oluşturuyorsun. Bu bash’ın bir özelliği, mkdir’ın değil — ama ikisini birlikte kullanınca gerçekten güçlü bir kombinasyon elde ediyorsun.

💡İpucu: Brace expansion’ı kullanırken süslü parantezler arasında boşluk bırakma. {public, src} değil {public,src} yazmalısın. Boşluk bırakırsan bash bunu tek bir string olarak yorumlar ve beklediğin sonucu alamazsın.

-m Parametresi: Dizini Oluştururken İzinleri Ayarla

Bu parametre, özellikle web sunucusu kurulumlarında seni ayrı bir chmod adımından kurtarır. Dizini oluştururken aynı anda izinlerini de belirleyebilirsin.

# 755 izniyle dizin oluştur (web dizinleri için yaygın)
mkdir -m 755 /var/www/mywebsite

# 700 izniyle gizli/hassas dizin oluştur
mkdir -m 700 /var/www/mywebsite/private

# -p ile birlikte kullanım
mkdir -m 755 -p /var/www/mywebsite/public_html

# Yalnızca sahibinin okuyabileceği log dizini
mkdir -m 600 /var/www/mywebsite/secure_logs
Uyarı: -m parametresini -p ile birlikte kullandığında dikkatli ol. -m yalnızca en son oluşturulan (hedef) dizine uygulanır, ara üst dizinlere değil. Üst dizinlerin izinleri umask değerinden etkilenir. Kritik ortamlarda her dizinin iznini ayrıca doğrula.

-v Parametresi: Ne Olduğunu Gör

-v (verbose) parametresi, oluşturulan her dizin için ekrana bilgi yazar. Script yazarken veya büyük bir yapı oluştururken gerçekten ne yapıldığını görmek istiyorsan bu bayrağı ekle.

# Verbose mod ile dizin oluştur
mkdir -pv /var/www/newsite/{public_html,logs,ssl}

# Örnek çıktı:
# mkdir: created directory '/var/www/newsite'
# mkdir: created directory '/var/www/newsite/public_html'
# mkdir: created directory '/var/www/newsite/logs'
# mkdir: created directory '/var/www/newsite/ssl'

Özellikle büyük otomasyonlarda ya da bir junior’a bir şeyler anlatırken verbose mod çok işe yarıyor. Ne oluşturuldu, ne oluşturulmadı — her şey gözünün önünde.

Tüm Parametreler Hızlı Başvuru Tablosu

ParametreUzun AdAçıklamaÖrnek
-p--parentsEksik üst dizinleri de oluşturur, var olanlar için hata vermezmkdir -p /a/b/c
-m--modeDizin izinlerini belirler (chmod formatında)mkdir -m 755 /dir
-v--verboseHer oluşturulan dizin için mesaj yazarmkdir -v /dir
-ZSELinux bağlamını varsayılana ayarlarmkdir -Z /dir
--helpYardım metnini gösterirmkdir --help
--versionSürüm bilgisini gösterirmkdir --version

Gerçek Dünya Senaryosu 1: Apache Web Sunucusu Kurulumu

Yeni bir Apache sanal sunucusu (virtual host) kuruyorsun. Standart dizin yapısını elle tek tek oluşturmak yerine aşağıdaki script’i kullan. Bu benim yıllardır kullandığım, ufak tefek geliştirdiğim bir yaklaşım.

#!/bin/bash
# Apache sanal sunucusu için dizin yapısı oluşturma scripti

DOMAIN="example.com"
WEBROOT="/var/www"
WWW_USER="www-data"

# Ana dizin yapısını oluştur
mkdir -pv ${WEBROOT}/${DOMAIN}/{public_html,logs,ssl,backup}

# Log dizini için özel izinler
mkdir -m 750 -p ${WEBROOT}/${DOMAIN}/logs

# Public HTML için doğru izinler
chmod 755 ${WEBROOT}/${DOMAIN}/public_html

# Sahipliği web sunucusu kullanıcısına ver
chown -R ${WWW_USER}:${WWW_USER} ${WEBROOT}/${DOMAIN}

# Doğrulama
ls -la ${WEBROOT}/${DOMAIN}/
echo "Dizin yapısı ${DOMAIN} için oluşturuldu."

Bu script’i /usr/local/bin/setup-vhost.sh olarak kaydedip çalıştırılabilir yaparsan, her yeni domain için tek satırla kullanabilirsin. Domain adını değişken olarak geçirmek istersen script’e parametre desteği eklemek de çok basit.

Gerçek Dünya Senaryosu 2: Nginx + PHP-FPM Projesi

Nginx kullananlar için biraz farklı bir yapı tercih ediliyor. Özellikle PHP-FPM ile çalışıyorsan, socket dosyası için ayrı bir dizin, önbellek için ayrı bir alan lazım.

# Nginx + PHP-FPM projesi için tam dizin yapısı
PROJECT="myapp"

mkdir -pv /var/www/${PROJECT}/{public,storage/{logs,cache,sessions,uploads},config}

# PHP-FPM socket dizini
mkdir -m 710 -p /run/php/${PROJECT}

# Nginx önbellek dizini
mkdir -m 755 -p /var/cache/nginx/${PROJECT}

# İzinleri ayarla
chown -R www-data:www-data /var/www/${PROJECT}/storage
chmod -R 775 /var/www/${PROJECT}/storage

# Yapıyı görüntüle
find /var/www/${PROJECT} -type d | sort
Bilgi: Laravel gibi PHP framework’leri kullanıyorsan, storage dizininin altındaki klasörlerin www-data tarafından yazılabilir olması şart. Yoksa session, cache ve log sorunlarıyla karşılaşırsın. mkdir -m 775 ile oluşturmak bu sorunu baştan çözer.

Gerçek Dünya Senaryosu 3: Node.js / Next.js Projesi

Node.js tabanlı bir uygulama deploy ediyorsun. PM2 ile çalışıyorsa log dosyaları için, statik dosyalar için ve uploads için yapıyı önceden kurmak işleri kolaylaştırır.

# Node.js projesi için dizin yapısı
APP_NAME="nextjs-app"
APP_DIR="/var/www/${APP_NAME}"

# Ana yapı
mkdir -pv ${APP_DIR}/{current,releases,shared/{logs,uploads,config}}

# PM2 log dizini
mkdir -m 755 -p /home/deploy/.pm2/logs

# Nginx statik dosyalar için
mkdir -m 755 -p /var/www/${APP_NAME}/public/static

# Sahiplik ataması (deploy kullanıcısı varsayılıyor)
chown -R deploy:deploy ${APP_DIR}
chown -R www-data:www-data ${APP_DIR}/public

echo "Node.js proje yapısı hazır: ${APP_DIR}"

Windows’ta mkdir: PowerShell ve CMD

Windows tarafında iş yapıyorsan da mkdir komutu var, hem CMD hem PowerShell’de çalışır. Ama davranış biraz farklı, bunu bilmekte fayda var.

CMD’de mkdir ve md aynı şeydir. -p bayrağına gerek yok, CMD varsayılan olarak üst dizinleri oluşturur:

# PowerShell ile tek dizin
New-Item -ItemType Directory -Path "C:inetpubmysite"

# PowerShell ile iç içe dizin yapısı (-Force var olan dizinde hata vermez)
New-Item -ItemType Directory -Force -Path "C:inetpubmysitelogs"
New-Item -ItemType Directory -Force -Path "C:inetpubmysiteuploads"
New-Item -ItemType Directory -Force -Path "C:inetpubmysitessl"

# mkdir alias'ı PowerShell'de de çalışır
mkdir -Force "C:inetpubmysitepublic"

# Birden fazla dizin oluştur (döngüyle)
$dirs = @("logs", "uploads", "ssl", "backup", "config")
foreach ($dir in $dirs) {
    New-Item -ItemType Directory -Force -Path "C:inetpubmysite$dir"
    Write-Host "Oluşturuldu: C:inetpubmysite$dir"
}
Bilgi: PowerShell’de mkdir aslında New-Item -ItemType Directory komutunun bir alias’ıdır. Her ikisi de aynı işi yapar ama script’lerde okunabilirlik açısından tam adını kullanmak daha iyidir.

Sık Yapılan Hatalar ve Çözümleri

Hata 1: “cannot create directory: No such file or directory”

Üst dizin yok, -p kullanmadın. Çözüm basit:

# Hatalı kullanım
mkdir /var/www/site/public_html  # /var/www/site henüz yok

# Doğru kullanım
mkdir -p /var/www/site/public_html

Hata 2: “Permission denied”

Hedef konumda yazma izniniz yok. sudo kullanman ya da doğru kullanıcıya geçmen gerekiyor:

# Permission denied aldığında
sudo mkdir -p /var/www/mysite

# Sonra kendi kullanıcına veya www-data'ya sahipliği ver
sudo chown -R $USER:$USER /var/www/mysite
# ya da
sudo chown -R www-data:www-data /var/www/mysite

Hata 3: Yanlış İzinle Oluşturulmuş Dizin

Umask değerin beklenenden farklı izinler üretebilir. Özellikle shared hosting ortamlarında ya da özelleştirilmiş sunucularda bu başını ağrıtabilir.

# Mevcut umask değerini kontrol et
umask

# Dizin oluşturduktan sonra izni kontrol et
ls -ld /var/www/mysite

# İzni düzelt
chmod 755 /var/www/mysite

# Alternatif: Kesin izinle mkdir kullan
mkdir -m 755 -p /var/www/mysite
Uyarı: Web dizinlerinde asla 777 izni kullanma. Bu, sunucudaki herhangi bir kullanıcının veya güvenlik açığı yoluyla saldırganın dizine yazmasına izin verir. Web sunucusu için standart olan 755 (dizinler) ve 644 (dosyalar) kombinasyonu çoğu durumda yeterlidir. Özel yazma ihtiyacı varsa sahipliği doğru kullanıcıya ata.

Bonus: Tarih Bazlı Log Dizinleri Oluşturma

Log yönetimi yapıyorsan, tarihe göre otomatik dizin oluşturmak çok işe yarıyor. Bunu cron job’a bağlarsan her gece otomatik olarak çalışır.

#!/bin/bash
# Tarih bazlı log dizini oluşturma - cron'a eklenebilir

LOG_BASE="/var/log/myapp"
DATE=$(date +%Y/%m/%d)

# Bugünün tarihine göre dizin oluştur
mkdir -pv "${LOG_BASE}/${DATE}"

# Sahipliği ayarla
chown www-data:www-data "${LOG_BASE}/${DATE}"

# 30 günden eski log dizinlerini sil
find ${LOG_BASE} -type d -mtime +30 -exec rm -rf {} + 2>/dev/null

echo "Log dizini hazır: ${LOG_BASE}/${DATE}"

Bu script’i /etc/cron.daily/ altına koyarsan sistem her gece otomatik çalıştırır. Hem yeni dizini hazırlar hem de eski logları temizler.

Özet

mkdir, basit görünümünün arkasında güçlü bir araç. Özellikle şu noktaları aklında tut:

  • -p parametresi olmadan çalışıyorsan eksik kalıyorsun. Her script’inde kullan.
  • -m ile izinleri baştan belirle, sonradan chmod ile uğraşma.
  • -v parametresi, özellikle otomasyonda debug için çok değerli.
  • Brace expansion ile tek komutta karmaşık dizin yapıları oluşturabilirsin.
  • Web sunucusu dizinlerinde izin yönetimini asla ihmal etme; 777 kesinlikle hayır.
  • Windows’ta mkdir çalışır ama PowerShell’de New-Item -ItemType Directory -Force tercih edilmeli.

Sonraki Adımlar

mkdir’ı kavradıktan sonra sıradaki adımlar şunlar olabilir:

  • chmod ve chown: Dizin izinlerini ve sahipliğini tam anlamıyla kontrol etmeyi öğren. mkdir ile başladığın iş, bu komutlarla tamamlanıyor.
  • find komutu: Oluşturduğun dizin yapılarını yönetmek, aramak ve toplu işlemler yapmak için şart.
  • Bash scripting: mkdir tek başına güçlü ama bir script içinde değişkenler, döngüler ve koşullarla birleşince gerçek gücünü ortaya koyuyor.
  • rsync ile dizin senkronizasyonu: Oluşturduğun yapıları sunucular arasında taşımak için rsync’i incele.
  • ACL (Access Control Lists): Temel chmod izinlerinin yetmediği durumlarda, ACL ile daha ince izin yönetimi yapabilirsin.

Sorun yaşıyorsan ya da farklı bir senaryon varsa yorumlarda anlat, bakıp yanıtlarım. Sysadmin dünyasında kimse her şeyi tek başına öğrenmez, paylaşmak meseleye dahil.

cd Komutu: Dizinler Arasında Gezinme Teknikleri — Web Sunucusu Yöneticileri İçin Pratik Rehber

Terminal’de her gün onlarca kez kullandığın cd komutu aslında sandığından çok daha güçlü. Web sunucusu yönetiminde zamandan kazandıracak gezinme tekniklerini, kısayolları ve püf noktaları bu yazıda derledim.

Terminali açtığında ilk yaptığın şey nedir? Büyük ihtimalle bir cd yazıyorsun ve bir yerlere gitmeye çalışıyorsun. Yani günde belki yüz kez kullandığın bu komut hakkında ne kadar şey bildiğini hiç düşündün mü? Şimdi düşün: eğer bu komutu yüzde elli daha verimli kullansaydın, yılda ne kadar zaman kazanırdın?

Web sunucusu yöneticisi olarak zamanının büyük bir kısmını terminal’de geçiriyorsun. Apache config dosyaları, Nginx vhost’ları, PHP-FPM havuzları, log dizinleri… Bunlar arasında sürekli gidip geliyorsun. Bu yazıda cd komutunun temellerinden başlayıp, seni gerçekten hızlandıracak ileri tekniklere kadar her şeyi ele alacağım. Hazırsan başlayalım.

cd Komutunun Temelleri — Bildiğini Sandıkların

Evet, cd dizin_adı ile dizine girersin. Bunu zaten biliyorsun. Ama temel kullanımı hızlıca geçelim ki aynı sayfada olalım, ardından asıl güzel kısımlara geçeceğiz.

# Mutlak yol ile dizine git
cd /var/www/html

# Göreli yol ile dizine git
cd html

# Bir üst dizine git
cd ..

# İki üst dizine git
cd ../..

# Home dizinine dön (üç farklı yöntem, hepsi aynı işi yapar)
cd
cd ~
cd $HOME

Bunları biliyorsun, tamam. Şimdi asıl meseleye gelelim.

Web Sunucusu Yöneticisinin Olmazsa Olmazı: Hızlı Dizin Geçişleri

Bir web sunucusunda çalışırken dizin yapısı oldukça derinleşebilir. Örneğin bir müşterinin Apache virtual host konfigürasyonunu düzenleyip ardından log dosyalarına bakmak istediğinde, birkaç farklı dizin arasında sürekli gidip geliyorsun. İşte bu noktada hayatını kolaylaştıracak ilk teknik: tire (-) kısayolu.

# Şu an /var/www/html/musteri1/public_html konumundasın
cd /var/log/apache2

# Düz log dosyalarına baktın, şimdi geri dönmek istiyorsun
cd -
# Çıktı: /var/www/html/musteri1/public_html
# ve otomatik olarak oraya gidersin

# Bu iki dizin arasında ping-pong gibi gidip gelebilirsin
cd -
cd -
cd -
💡İpucu: cd - komutu aslında $OLDPWD ortam değişkenini kullanır. Önceki dizine dönmek için harika bir kısayol, özellikle config dosyası ile log dizini arasında gidip gelirken zaman kazandırır.

CDPATH: Arama Yolu Tanımlama

Bu özelliği kullanan sysadmin sayısı şaşırtıcı biçimde az. CDPATH, tıpkı PATH ortam değişkeni gibi çalışır ama dizin geçişleri için. Bir kez tanımladıktan sonra, o dizinlerin alt klasörlerine tam yol vermeden girebilirsin.

# ~/.bashrc veya ~/.bash_profile dosyasına ekle
export CDPATH=.:~:/var/www:/etc/apache2:/etc/nginx

# Artık şu şekilde kullanabilirsin:
# /var/www altındaki bir dizine tam yol vermeden girebilirsin
cd html          # Otomatik /var/www/html olarak çözümlenir
cd sites-enabled # Otomatik /etc/apache2/sites-enabled olarak çözümlenir
cd conf.d        # Otomatik /etc/nginx/conf.d olarak çözümlenir

# Değişikliği hemen uygulamak için
source ~/.bashrc

Bu ayarı yaptıktan sonra, web sunucularında en çok kullandığın dizinlere tek kelimeyle ulaşabilirsin. Çok küçük görünüyor ama günde yüzlerce kez bunu yapıyorsan, fark önemli.

Gerçek Dünya Senaryosu: Multi-Site Web Sunucusunda Hızlı Gezinme

Diyelim ki onlarca web sitesi barındıran bir sunucuyu yönetiyorsun. Nginx kullanıyorsun ve bir müşteriden şikâyet geldi: site yavaş açılıyor ve bazı 502 hataları var. İnceleme sürecinde hangi dizinlere gideceksin?

  • /etc/nginx/sites-enabled/ — Virtual host konfigürasyonu
  • /var/log/nginx/ — Hata ve erişim logları
  • /var/www/musteri-adi/ — Site dosyaları
  • /etc/php/8.1/fpm/pool.d/ — PHP-FPM havuz ayarları
  • /var/log/php8.1-fpm.log — PHP-FPM logları

Bu senaryoda nasıl hızlı gezinebilirsin? İşte pratik bir akış:

# Önce Nginx config'e bak
cd /etc/nginx/sites-enabled
ls -la
cat musteri-sitesi.conf

# Hızla log dizinine geç
cd /var/log/nginx
tail -n 50 error.log | grep musteri-sitesi

# Bir önceki dizine (sites-enabled) hızlıca geri dön
cd -

# PHP-FPM havuzuna git
cd /etc/php/8.1/fpm/pool.d
cat musteri-sitesi.conf

# Site dosyalarına bak
cd /var/www/musteri-sitesi/public_html
ls -la

# Herhangi bir anda config dizinine geri dön
cd /etc/nginx/sites-enabled

# Değişiklik sonrası tekrar site dosyalarına:
cd -
Bilgi: Web sunucusu sorun giderme sırasında genellikle 2-3 dizin arasında gidip gelirsin. cd - bu senaryolarda en büyük zaman kazandırıcındır. Daha fazla dizin gerektiğinde ise aşağıda anlatacağım pushd/popd mekanizması devreye girer.

pushd ve popd: Dizin Yığını ile Çalışmak

Birden fazla dizin arasında organize biçimde geçiş yapman gerektiğinde pushd ve popd ikilisi imdadına yetişir. Bu ikili, bir yığın (stack) yapısı kullanır. Dizinleri yığına itersin, işin bitince geri çekersin.

# pushd ile dizine git ve yığına kaydet
pushd /etc/nginx/sites-enabled
# Çıktı: /etc/nginx/sites-enabled ~

pushd /var/log/nginx
# Çıktı: /var/log/nginx /etc/nginx/sites-enabled ~

pushd /etc/php/8.1/fpm/pool.d
# Çıktı: /etc/php/8.1/fpm/pool.d /var/log/nginx /etc/nginx/sites-enabled ~

# Yığını görüntüle
dirs -v
# Çıktı:
#  0  /etc/php/8.1/fpm/pool.d
#  1  /var/log/nginx
#  2  /etc/nginx/sites-enabled
#  3  ~

# Numarayla doğrudan o dizine git
cd ~2
# Artık /etc/nginx/sites-enabled konumundasın

# Yığından çıkar ve bir önceki dizine dön
popd
# Çıktı: /var/log/nginx /etc/nginx/sites-enabled ~

popd
# Çıktı: /etc/nginx/sites-enabled ~

popd
# Çıktı: ~
# Artık home dizinindesin

Bu teknik özellikle karmaşık bakım süreçlerinde, birden fazla konfigürasyon dosyası arasında gezerken çok işe yarıyor. Yığına attığın dizinleri unutmayacaksın çünkü dirs -v ile her zaman görebilirsin.

Tab Tamamlama: Hâlâ Tam Adını mı Yazıyorsun?

Bunu söylemek zorundayım: eğer dizin adlarını hâlâ harfi harfine yazıyorsan, bunu oku. Tab tuşu senin en iyi arkadaşın. Ama birçok kişi tab tamamlamanın gücünü tam olarak kullanmıyor.

# Kısmi isim yaz ve Tab'a bas
cd /var/www/mu[TAB]
# Eğer tekil eşleşme varsa otomatik tamamlar
# /var/www/musteri-sitesi/

# Birden fazla eşleşme varsa Tab'a iki kez bas
cd /var/www/[TAB][TAB]
# Çıktı:
# musteri1/   musteri2/   musteri3/   html/

# Uzun dizin adlarında özellikle faydalı
cd /etc/letsencrypt/live/[TAB][TAB]
# Tüm domain klasörlerini listeler

# bash-completion paketi kuruluysa daha da akıllı çalışır
sudo apt install bash-completion   # Debian/Ubuntu
sudo yum install bash-completion   # RHEL/CentOS
💡İpucu: bash-completion paketi kurulu olduğunda Tab tamamlama yalnızca dizin adlarını değil, komut argümanlarını, paket adlarını ve çok daha fazlasını tamamlayabilir hale gelir. Eğer sunucunda kurulu değilse hemen kur.

Glob Desenleri ile cd Kullanımı

Dizin adının bir kısmını biliyorsun ama tam adını hatırlamıyorsun? Glob desenleri burada devreye girer. Ama dikkatli ol, birden fazla eşleşme varsa beklenmedik sonuçlar alabilirsin.

# Yıldız glob ile dizine gir (tek eşleşme varsa çalışır)
cd /var/www/must*
# /var/www/musteri-sitesi'ne gider

# Soru işareti (tek karakter yerine geçer)
cd /etc/php/?.?/fpm
# /etc/php/8.1/fpm veya /etc/php/7.4/fpm gibi

# Süslü parantez ile alternatifler
cd /etc/{nginx,apache2}
# Hata verir çünkü ikisi de var; ama script içinde kontrol için kullanışlı

# Hangi dizinlerin eşleştiğini önce kontrol et
ls -d /var/www/must*
# Çıktıyı gördükten sonra cd ile git
Uyarı: Glob desenleri birden fazla dizinle eşleşirse cd komutu yalnızca alfabetik sıradaki ilk eşleşmeye gider ve diğerlerini sessizce yok sayar. Üretim sunucusunda beklediğin yerde olmayabilirsin. Tab tamamlama bu durumda daha güvenlidir.

Alias Tanımlama: Sık Gidilen Dizinler İçin Kısayollar

Web sunucusu yöneticisi olarak her gün aynı dizinlere gidiyorsun. Bu dizinler için alias tanımlamak, uzun yolları ezberleme derdini ortadan kaldırır.

# ~/.bashrc dosyasına ekle
# Web sunucusu dizinleri
alias cdwww='cd /var/www/html'
alias cdnginx='cd /etc/nginx'
alias cdapache='cd /etc/apache2'
alias cdlogs='cd /var/log/nginx'
alias cdfpm='cd /etc/php/8.1/fpm/pool.d'
alias cdssl='cd /etc/letsencrypt/live'
alias cdsites='cd /etc/nginx/sites-enabled'

# Özel müşteri dizinleri (sunucuya göre özelleştir)
alias cdmust1='cd /var/www/musteri1/public_html'
alias cdmust2='cd /var/www/musteri2/public_html'

# Değişiklikleri uygula
source ~/.bashrc

# Artık kullanabilirsin
cdlogs
# /var/log/nginx dizinine gider

cdsites
# /etc/nginx/sites-enabled dizinine gider

Bu alias’ları bir kez tanımladıktan sonra hayatın çok daha kolay hale gelir. Yeni bir sunucuya geçtiğinde bu .bashrc dosyasını yanında götür ya da bir dotfiles reposu oluştur.

Fonksiyon Tabanlı Akıllı Gezinme

Alias yetmediğinde Bash fonksiyonları devreye girer. Mesela hangi müşteri sitesine gideceğini parametre olarak geçebileceğin bir fonksiyon yazabilirsin:

# ~/.bashrc dosyasına ekle

# Müşteri site dizinine hızlı erişim
cdsite() {
    local site_path="/var/www/$1"
    if [ -d "$site_path" ]; then
        cd "$site_path" && echo "Dizin: $site_path"
        ls -la
    else
        echo "Hata: $site_path bulunamadı."
        echo "Mevcut siteler:"
        ls /var/www/
    fi
}

# Nginx log dosyasına hızlı erişim
cdlog() {
    if [ -z "$1" ]; then
        cd /var/log/nginx && ls -lt | head -20
    else
        cd /var/log/nginx && tail -f "$1".access.log
    fi
}

# Kullanım:
cdsite musteri1
# /var/www/musteri1 dizinine gider ve içeriği listeler

cdsite yanlisad
# Hata: /var/www/yanlisad bulunamadı.
# Mevcut siteler: musteri1 musteri2 html

Sembolik Linkler ve cd: Dikkat Edilmesi Gerekenler

Web sunucularında sembolik linkler son derece yaygın. Nginx’in sites-enabled dizini, sites-available‘daki konfigürasyonlara sembolik link içerir. Bu noktada cd ile gezinirken bazı farklılıklar ortaya çıkabilir.

# Sembolik link üzerinden dizine git
cd /etc/nginx/sites-enabled
ls -la
# musteri1.conf -> /etc/nginx/sites-available/musteri1.conf

# pwd komutu mantıksal yolu gösterir (varsayılan davranış)
pwd
# /etc/nginx/sites-enabled

# Fiziksel (gerçek) yolu görmek için -P flag'i
pwd -P
# /etc/nginx/sites-enabled (eğer dizinin kendisi link değilse)

# cd -P ile sembolik linkleri takip etmeden fiziksel dizine git
cd -P /var/www/html
# Eğer html bir sembolik link ise, gerçek dizine gider

# cd -L ile mantıksal yolu koru (varsayılan)
cd -L /var/www/html

# Örnek: Yanlış anlama durumu
ln -s /srv/web/musteri1 /var/www/musteri1
cd /var/www/musteri1
pwd
# /var/www/musteri1 (mantıksal yol)

cd -P /var/www/musteri1
pwd
# /srv/web/musteri1 (fiziksel yol)
Uyarı: Script yazarken sembolik linklerin takip edilip edilmediği kritik önem taşıyabilir. Özellikle dosya izinlerini ve sahipliğini değiştirdiğinde, yanlış dizinde işlem yapıyor olabilirsin. Script içinde her zaman pwd -P ile gerçek konumu doğrula.

Karşılaştırma Tablosu: cd Tekniklerinin Kullanım Alanları

TeknikKomutEn İyi Kullanım AlanıZorluk
Önceki dizine döncd -2 dizin arası geçişKolay
Dizin yığınıpushd/popd3+ dizin arası geçişOrta
CDPATHexport CDPATH=...Sık gidilen üst dizinlerKolay
Aliasalias cdlogs=...Sabit dizin kısayollarıKolay
Bash Fonksiyonucdsite() {...}Dinamik parametre gereken durumlarOrta
Tab TamamlamaTab / Tab TabHer zaman, her yerdeKolay
Fiziksel yolcd -PSembolik link ortamlarıKolay

Bonus: zsh ve fish Kullanıcıları İçin Ekstralar

Eğer sunucularda Bash yerine zsh veya fish kullanıyorsan (ki bazı modern sistemlerde varsayılan shell zsh oldu), ekstra güçlere sahipsin demektir.

# zsh: AUTO_CD özelliği — cd yazmana gerek kalmaz!
# ~/.zshrc dosyasına ekle:
setopt AUTO_CD

# Artık sadece dizin adını yazman yeterli
/var/www/html
# Otomatik olarak o dizine gider

# zsh: Dizin adındaki hataları düzeltme
setopt CORRECT

# zsh: Kısa yol değiştirme — mevcut yoldaki bir kısmı değiştir
# Şu an /var/www/musteri1/public_html konumundasın:
cd musteri1 musteri2
# /var/www/musteri2/public_html'e gider
# Bu özellik bash'te yoktur ama zsh'de çok kullanışlıdır!

# Oh-My-Zsh kullanıyorsan 'd' komutu dizin geçmişini gösterir
d
# 0  /var/www/musteri1/public_html
# 1  /etc/nginx/sites-enabled
# 2  /var/log/nginx
# Sonra sadece numara yaz: 2 -> /var/log/nginx'e gider
Bilgi: zsh’nin cd musteri1 musteri2 sözdizimi (yol parçası değiştirme) birden fazla aynı yapıda site barındıran web sunucularında inanılmaz derecede kullanışlıdır. Benzer dizin yapıları arasında tek komutla geçiş yapabilirsin.

Özet: Hangisini Ne Zaman Kullan?

Tüm bu teknikleri kafana yüklemene gerek yok. Şu basit karar ağacını takip et:

  • Sadece bir önceki dizine mi dönmek istiyorsun?cd - kullan
  • 3 veya daha fazla dizin arasında organize geçiş mi yapacaksın?pushd/popd kullan
  • Belirli üst dizinlerin altına hızlı erişim mi istiyorsun?CDPATH tanımla
  • Sürekli aynı dizinlere mi gidiyorsun? → Alias veya fonksiyon yaz
  • Dizin adını tam hatırlamıyorsun? → Tab Tab ile listele
  • Sembolik link ortamında mısın?cd -P ile fiziksel yola git

Sonraki Adımlar

Bu yazıda anlattıkları hemen uygulamak istiyorsan şu sırayla başla:

  • Bugün: cd - ve pushd/popd kullanmaya başla. Birkaç gün içinde refleks haline gelir.
  • Bu hafta: ~/.bashrc dosyana web sunucusu dizinleri için alias’lar ekle. CDPATH değişkenini yapılandır.
  • Bu ay: Tekrarlayan iş akışlarını analiz et ve bunlar için Bash fonksiyonları yaz. Dotfiles reposu oluşturmayı düşün.
  • İleri seviye: autojump veya zoxide araçlarını incele. Bunlar dizin geçmişini öğrenerek en sık gidilen yerlere tek harfle ulaşmanı sağlar.

Terminal’de hız, küçük alışkanlıkların birikmesiyle gelir. cd gibi görünüşte basit bir komutla dakikalar, hatta saatler kazanabilirsin. Önemli olan bu teknikleri okuyup geçmemek; hemen denemek ve alışkanlık haline getirmek. Şimdi terminali aç ve bir dene.