cat Komutu: Linux’ta Dosya İçeriği Görüntüleme ve Birleştirme

Terminal açtığında ilk öğrendiğin komutlardan biri muhtemelen cat olmuştur. Basit görünür, belki de fazla basit. Ama yıllar geçtikçe fark edersin ki cat aslında sysadmin işlerinin vazgeçilmez bir parçası. Hem dosya içeriği görüntülemede hem de dosyaları birleştirmede, hem de pipe zincirlerinde sürekli karşına çıkar. Bu yazıda cat komutunu sadece yüzeysel değil, gerçek dünya senaryolarıyla birlikte ele alacağız.

cat Komutu Nedir?

cat, “concatenate” kelimesinin kısaltmasıdır. Türkçeye “birleştirmek” olarak çevirebiliriz. Unix dünyasında 1970’lerden beri var olan bu komut, dosya içeriklerini standart çıktıya (stdout) yazan bir araçtır. Yani terminaline bastırır, ya da yönlendirme operatörleriyle başka yerlere gönderir.

Komutun temel yapısı şöyledir:

cat [SEÇENEKLER] [DOSYA...]

Birden fazla dosya verebilirsin, boşlukla ayırarak. Dosya vermezsen stdin’den okur, yani klavyeden yazıp Enter’a basarken her satırı tekrar ekrana basar. Çıkmak için Ctrl+C ya da Ctrl+D kullanırsın.

Temel Kullanım Örnekleri

Dosya İçeriği Görüntüleme

En temel kullanım şekli, bir dosyanın içeriğini ekrana basmaktır:

cat /etc/hostname
cat /etc/os-release
cat /proc/cpuinfo

/proc/cpuinfo gibi sanal dosyaları okumak için cat biçilmiş kaftandır. less veya more ile de açabilirsin ama küçük dosyalarda cat çok daha hızlıdır.

Birden Fazla Dosyayı Birleştirme

cat dosya1.txt dosya2.txt dosya3.txt

Bu komut üç dosyanın içeriğini sırayla ekrana basar. Eğer bunları tek bir dosyada toplamak istiyorsan:

cat dosya1.txt dosya2.txt dosya3.txt > birlestir.txt

Dikkat et: Tek > operatörü varolan dosyanın üzerine yazar. >> ise sonuna ekler.

Önemli Parametreler

-n: Tüm satırlara numara ekler. Log analizi yaparken çok işe yarar.

-b: Yalnızca boş olmayan satırlara numara ekler. -n‘den daha temiz bir çıktı verir.

-s: Birden fazla arka arkaya gelen boş satırı tek boş satıra indirir. Dağınık yapılandırma dosyalarını okurken nefes aldırır.

-A: Satır sonlarını $ ile, tab karakterlerini ^I ile gösterir. Gizli karakterleri tespit etmek için mükemmeldir.

-v: Yazdırılamayan karakterleri görünür hale getirir.

-e: Satır sonlarını $ ile gösterir, -v ile kombinedir.

-t: Tab karakterlerini ^I olarak gösterir, -v ile kombinedir.

-T: Yalnızca tab karakterlerini ^I olarak gösterir.

-E: Satır sonlarına $ ekler, Windows’tan kopyalanan dosyalardaki CRLF sorunlarını bulmak için kullanışlıdır.

–help: Yardım ekranını gösterir.

–version: Versiyon bilgisini verir.

Gerçek Dünya Senaryoları

Senaryo 1: Log Dosyası Analizi

Bir üretim sunucusunda servis aniden durdu. SSH ile bağlandın, ilk iş log dosyasına bakmak:

cat /var/log/syslog | grep "error" | tail -50

Ya da daha spesifik bir servis için:

cat /var/log/nginx/error.log | grep "$(date +%Y/%m/%d)" | grep -i "502|503|504"

Bu komut bugünün tarihine ait 502, 503 ve 504 hatalarını filtreler. Gece 3’te alarm geldiğinde tek satırla durumu anlayabilmek paha biçilmezdir.

Satır numaralarıyla birlikte incelemek istersen:

cat -n /var/log/nginx/access.log | tail -100

Böylece hata satırının tam numarasını bilir, sed ile ilgili bölgeyi kesip alabilirsin.

Senaryo 2: Yapılandırma Dosyası Oluşturma

cat ile here-doc kullanarak tek hamlede yapılandırma dosyası oluşturabilirsin. Bu özellikle otomasyon scriptlerinde ve Ansible playbook’larında çok sık kullanılan bir tekniktir:

cat > /etc/nginx/conf.d/myapp.conf << 'EOF'
server {
    listen 80;
    server_name myapp.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF

'EOF' şeklinde tek tırnak içine alman önemli. Böylece $host ve $remote_addr gibi değişkenler expand edilmez, olduğu gibi dosyaya yazılır. Eğer değişkenlerin shell tarafından işlenmesini istiyorsan EOF şeklinde tırnaksız kullanırsın.

Senaryo 3: SSH Authorized Keys Yönetimi

Yeni bir kullanıcıya SSH erişimi vermek için public key’i authorized_keys dosyasına eklemen gerekiyor:

cat id_rsa.pub >> /home/kullanici/.ssh/authorized_keys

Dikkat: Burada >> kullandık, > değil. > kullanırsan mevcut key’lerin üzerine yazar ve diğer kullanıcıların erişimi kesilir. Böyle bir hata gece yarısı çok pahalıya patlayabilir.

Birden fazla key eklemek istersen:

cat developer1.pub developer2.pub devops_lead.pub >> /home/deploy/.ssh/authorized_keys

Senaryo 4: Gizli Karakter Tespiti

Windows’tan kopyalanan bir script çalışmıyor. Satır sonları sorun çıkarıyor olabilir. -A parametresiyle kontrol edersin:

cat -A myscript.sh | head -20

Eğer her satırın sonunda ^M$ görüyorsan, Windows CRLF satır sonu karakterleriyle karşı karşıyasın demektir. Unix sadece $ görmelidir. Çözüm:

# dos2unix aracıyla düzeltme
dos2unix myscript.sh

# ya da sed ile
sed -i 's/r//' myscript.sh

Tab karakterlerini görünür kılmak için -T ya da -A kullanabilirsin. Özellikle Makefile yazarken tab/boşluk karmaşasını tespit etmekte hayat kurtarır:

cat -A Makefile | head -30

Tab’lar ^I olarak görünür, boşluklar normal görünür. Makefile’da boşluk olması gereken yerde tab varsa veya tam tersi, komutun hata verme sebebini anında anlarsın.

Senaryo 5: Dosya Birleştirme ve Yedek Alma

Birden fazla günlük log dosyasını tek arşivde toplamak istiyorsun:

cat /var/log/app/app.log.1 
    /var/log/app/app.log.2 
    /var/log/app/app.log.3 
    > /backup/app_logs_combined_$(date +%Y%m%d).log

Ya da glob pattern ile:

cat /var/log/app/app.log.* > /backup/app_all_logs.txt

Dikkat etmen gereken nokta: Glob pattern’ler alfabetik sıraya göre genişler. app.log.1, app.log.10, app.log.2 gibi bir durumda app.log.10, app.log.2‘den önce gelir. Bunu önlemek için önceden dosyaları sıralayıp pipe’layabilirsin:

ls -v /var/log/app/app.log.* | xargs cat > /backup/app_all_logs.txt

Senaryo 6: Sistem Bilgisi Okuma

Linux’ta pek çok sistem bilgisi /proc ve /sys altındaki sanal dosyalardan okunur. cat bu iş için mükemmeldir:

# CPU bilgisi
cat /proc/cpuinfo | grep "model name" | uniq

# RAM bilgisi
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable"

# Kernel sürümü
cat /proc/version

# Disk mount bilgileri
cat /proc/mounts

# Sistem uptime
cat /proc/uptime

# Network istatistikleri
cat /proc/net/dev

Bu dosyaları script içinde okumak, top, free, df gibi araçların çıktısını parse etmekten çok daha güvenilirdir. Araç versiyonları değişse de /proc arayüzü büyük ölçüde stabil kalır.

cat ile Pipe Zinciri Oluşturma

cat‘in en güçlü yanı diğer araçlarla birlikte kullanılmasıdır. Sysadmin işlerinde pipe zinciri hayatın merkezidir:

# En çok hata üreten IP'leri bul
cat /var/log/nginx/access.log | 
    grep " 500 " | 
    awk '{print $1}' | 
    sort | 
    uniq -c | 
    sort -rn | 
    head -10

Bu zincir şunları yapar: nginx log’unu okur, 500 hatalarını filtreler, IP adreslerini çıkarır, sıralar, tekrar edenleri sayar, en çoktan aza doğru tekrar sıralar ve ilk 10’u gösterir. Bir DDoS saldırısı ya da hatalı bir istemci varsa anında görürsün.

# Büyük dosyaları bul ve boyutlarıyla listele
cat /proc/mounts | 
    awk '{print $2}' | 
    xargs -I{} find {} -maxdepth 3 -size +100M 2>/dev/null | 
    head -20

“Useless Use of cat” Meselesi

Biraz teorik ama önemli bir konu. Sysadmin topluluğunda “UUOC” yani “Useless Use of Cat” denen bir antipattern var. Yani gereksiz cat kullanımı. Örneğin:

# Gereksiz cat kullanımı
cat dosya.txt | grep "hata"

# Daha doğrusu
grep "hata" dosya.txt

Pek çok araç doğrudan dosya adı alabilir ve bu daha verimlidir çünkü bir process daha az çalışır. Ancak bu durumu abartmamak gerekir. Pipe zincirinin okunabilirliği için bazen cat ile başlamak daha mantıklı olabilir. Özellikle dosya listesi dinamikse ya da ileride birden fazla dosya eklenecekse, cat ile başlayan zincir daha kolay genişletilebilir.

Pratik kural şudur: Tek bir dosya için grep, awk, sed gibi araçlara dosyayı doğrudan ver. Birden fazla dosya ya da karmaşık birleştirme işlemi söz konusuysa cat kullan.

tac Komutu: cat’in Tersi

Bonus olarak tac komutundan bahsetmek gerekir. cat‘in tersine, satırları ters sırada basar. İsim de oradan geliyor, “cat” kelimesinin tersi “tac”.

tac /var/log/syslog | head -50

Bu komut, log dosyasının en son 50 satırını gösterir ama tail -50‘den farklı olarak, ters sırada gösterir, yani en yeni kayıt en üstte çıkar. Sürekli akan bir log’da son olayları ilk görmek istiyorsan işe yarar.

Büyük Dosyalarda cat Kullanımı

Burada önemli bir uyarı yapmak gerekiyor. cat ile büyük dosyaları doğrudan terminale basmak pek de akıllıca değil. 10 GB’lık bir log dosyasını cat ile açarsan terminal bufferını doldurur ve anlamlı bir şey göremezsin. Büyük dosyalar için:

  • less: Sayfa sayfa gösterir, arama yapabilirsin
  • head: İlk N satırı gösterir
  • tail: Son N satırı gösterir
  • tail -f: Canlı olarak dosyayı izler

Ama büyük dosyayı grep, awk gibi araçlara pipe’lamak için cat kullanmak hala mantıklıdır. Terminale basmak yerine işleme sokuyorsun, bu farklı bir şey.

# 10 GB log dosyasında belirli IP'yi ara
cat /var/log/huge_access.log | grep "192.168.1.100" | wc -l

Ya da daha verimli:

grep -c "192.168.1.100" /var/log/huge_access.log

Pratik Script Örneği: Sistem Durumu Raporu

Gerçek hayatta kullanabileceğin bir script. cat ile sistem dosyalarını okuyup basit bir rapor oluşturuyor:

#!/bin/bash

RAPOR_DOSYASI="/tmp/sistem_raporu_$(date +%Y%m%d_%H%M%S).txt"

cat > "$RAPOR_DOSYASI" << EOF
=== SISTEM DURUM RAPORU ===
Tarih: $(date)
Sunucu: $(cat /etc/hostname)

--- ISLETIM SISTEMI ---
$(cat /etc/os-release | grep -E "^NAME|^VERSION=")

--- CPU BILGISI ---
$(cat /proc/cpuinfo | grep "model name" | uniq | cut -d: -f2 | xargs)
Cekirdek Sayisi: $(cat /proc/cpuinfo | grep "processor" | wc -l)

--- BELLEK DURUMU ---
$(cat /proc/meminfo | grep -E "MemTotal|MemAvailable|SwapTotal|SwapFree")

--- DISK DURUMU ---
$(df -h | grep -v tmpfs)

--- AKTIF SERVISLER ---
$(systemctl list-units --type=service --state=running | grep ".service" | head -20)

EOF

echo "Rapor olusturuldu: $RAPOR_DOSYASI"
cat "$RAPOR_DOSYASI"

Bu script hem here-doc ile rapor oluşturmak için cat kullanıyor hem de sistem dosyalarını okumak için. Sonunda da oluşturulan raporu terminale basıyor. Basit ama işlevsel.

cat ile Dosya Sıfırlama

Bazen bir dosyayı silmek yerine içini boşaltmak istersin. Özellikle log dosyalarında bu işe yarar:

# Dosya içeriğini sıfırla ama dosyayı silme
cat /dev/null > /var/log/myapp/debug.log

# Alternatif yol
> /var/log/myapp/debug.log

# truncate komutuyla da yapılabilir
truncate -s 0 /var/log/myapp/debug.log

cat /dev/null > dosya ile > dosya aynı işi yapar. /dev/null her zaman boş veri döndürür, bu içeriği dosyaya yazınca dosya sıfırlanır. Bazı sysadminler cat /dev/null > formunu tercih eder çünkü okuyunca amacı daha açık anlaşılır.

Sık Yapılan Hatalar

> ile >> karıştırmak: En klasik hata. > dosyayı sıfırdan yazar, >> sonuna ekler. Kritik bir dosyanın üzerine yazmak felaket olabilir.

Büyük dosyaları terminale basmak: Daha önce de söyledim, 500 MB’lık dosyayı cat ile açmaya çalışma. Önce wc -l ile kaç satır olduğuna bak, sonra karar ver.

Binary dosyaları cat ile açmak: Binary bir dosyayı cat ile açarsan terminal ekranın bozulabilir. file komutuyla önce dosya tipini kontrol et. Terminali düzeltmek için reset komutunu kullanabilirsin.

Here-doc’ta değişken expand etmeyi unutmak: Eğer cat > dosya << EOF kullanıyorsan ve içinde $DEGISKEN varsa, bu değişken expand edilir. Bunu istemiyorsan << 'EOF' ya da << EOF kullan.

Sonuç

cat komutu basit ama derindir. Temel kullanımı birkaç dakikada öğrenilir, ama incelikleri yıllar içinde ortaya çıkar. Log analizi, yapılandırma dosyası yönetimi, sistem bilgisi okuma, otomasyon scriptleri ve pipe zincirleri oluşturma gibi pek çok farklı alanda sürekli karşına çıkar.

Bir sysadmin olarak şunu söyleyebilirim: cat‘i küçümseme. Evet, bazı durumlarda daha uygun araçlar var. Evet, tek dosyayı grep‘e vermek daha verimli. Ama cat‘in esnekliği ve basitliği, onu terminal araç kutusunun vazgeçilmez bir parçası yapıyor. Özellikle gece yarısı bir üretim sorunuyla boğuşurken, düşünmeden yazabileceğin komutların değeri çok daha iyi anlaşılıyor.

Pratik yap, dene, kendi workflow’una entegre et. /proc dosyalarını keşfet, here-doc’u alışkanlık haline getir, pipe zincirlerini sev. cat sana bu kapıları açacak.

Yorum yapın