00 echo vs printf — ne zaman hangisi
Her iki komut da metin basar, ama davranışları ve taşınabilirlik garantileri farklı.
echo interaktif kabukta hızlı çıktı için idealdir: değer kontrol etmek, hata ayıklamak, tek satır mesaj basmak. Ancak -e flag'inin yorumlanması shell'den shell'e, sisteme göre ve hatta aynı shell'in farklı sürümlerine göre değişir.
printf POSIX standardında tanımlıdır, davranışı tahmin edilebilirdir ve C'nin printf() fonksiyonuna benzer format dizesi kullanır. Script yazarken — özellikle başka sistemlerde çalışacak ya da dash/sh ile yorumlanacak script'lerde — printf tercih edilmelidir.
İnteraktif kullanımda echo, script'lerde printf — bu alışkanlığı edinmek uzun vadede pişmanlıkları önler.
01 echo temel kullanım
echo tek argüman alır ve onu stdout'a yazar, ardından otomatik newline ekler.
# temel kullanım
echo "Merhaba dünya"
Merhaba dünya
# -n: sona newline ekleme
echo -n "Bitti: "
echo "tamam"
Bitti: tamam
# -e: escape dizilerini yorumla (bash built-in)
echo -e "Satır1\nSatır2\tSekme"
Satır1
Satır2 Sekme
# -E: escape dizilerini yorumlama (varsayılan, ama açık yazmak güvenli)
echo -E "Bu \n gerçek backslash-n"
Bu \n gerçek backslash-n
# değişken genişletme (çift tırnak içinde)
isim="Ali"
echo "Merhaba, $isim"
Merhaba, Ali
# değişken genişletme kapatmak (tek tırnak)
echo 'PATH değeri: $PATH'
PATH değeri: $PATH
echo $degisken yerine echo "$degisken" yazın. Tırnaksız kullanımda glob karakterleri ve IFS bölünmesi beklenmedik sonuç verir.
02 echo escape dizileri ve ANSI renkleri
echo -e veya printf ile terminal renkleri ve özel karakterler kullanılabilir.
# yaygın escape dizileri (-e gerektirir)
echo -e "\n" # yeni satır
echo -e "\t" # yatay sekme
echo -e "\\" # gerçek backslash
echo -e "\a" # alarm (bip sesi)
echo -e "\r" # satır başı (carriage return)
echo -e "\e" # ESC karakteri (= \033 = \x1b)
# ANSI renk kodları
# \e[RENKm ... \e[0m → ESC [ KOD m
echo -e "\e[31mKırmızı\e[0m" # ön plan kırmızı
echo -e "\e[32mYeşil\e[0m" # ön plan yeşil
echo -e "\e[1;33mKalın Sarı\e[0m" # kalın + sarı
echo -e "\e[44mMavi arka plan\e[0m" # arka plan mavi
# renk değişkenlerle script'te kullanım
RED='\e[31m'
GRN='\e[32m'
YLW='\e[33m'
RST='\e[0m'
echo -e "${RED}HATA${RST}: dosya bulunamadı"
echo -e "${GRN}TAMAM${RST}: işlem başarılı"
echo -e "${YLW}UYARI${RST}: disk dolmak üzere"
ANSI kodları terminale gönderildiğinde renklendirir; pipe'a veya dosyaya yönlendirildiğinde ham escape karakterleri görünür. [ -t 1 ] ile stdout'un terminal olup olmadığını kontrol edin, değilse renkleri devre dışı bırakın.
03 printf format dizesi temelleri
printf, C'nin printf() fonksiyonuna benzer format dizesi + argüman modelini kullanır. Newline otomatik eklenmez.
# temel sözdizimi: printf FORMAT [ARG...]
printf "Merhaba\n"
Merhaba
# %s: string argümanı
printf "İsim: %s\n" "Ali"
İsim: Ali
# %d: onluk tam sayı
printf "Yaş: %d\n" 30
Yaş: 30
# %f: ondalık sayı (varsayılan 6 basamak)
printf "Pi: %f\n" 3.14159
Pi: 3.141590
# birden fazla argüman — format tekrar edilir
printf "Öğe: %s\n" "elma" "armut" "kiraz"
Öğe: elma
Öğe: armut
Öğe: kiraz
# %x: onaltılık, %o: sekizlik
printf "Hex: 0x%x Oktal: 0%o\n" 255 255
Hex: 0xff Oktal: 0377
# %% gerçek yüzde işareti
printf "Doluluk: %d%%\n" 87
Doluluk: 87%
printf'e format'tan fazla argüman verilirse, format tekrar uygulanır. Bu özellik döngü yerine tek çağrıyla liste basmaya olanak verir.
04 printf genişlik, padding ve hizalama
Format belirtecine genişlik ve hassasiyet ekleyerek sütun hizalaması ve sayı biçimlendirmesi yapılır.
# %Ns: N karakter genişliğinde, sağa hizalı
printf "%10s | %5s\n" "isim" "yaş"
printf "%10s | %5d\n" "Ali" 30
printf "%10s | %5d\n" "Zeynep" 25
isim | yaş
Ali | 30
Zeynep | 25
# %-Ns: sola hizalı (eksi işareti)
printf "%-10s | %-5d\n" "Ali" 30
Ali | 30
# %0Nd: sıfır dolgulu tam sayı
printf "%05d\n" 42
00042
# %.Nf: N basamak hassasiyet
printf "%.2f\n" 3.14159
3.14
# %N.Mf: toplam genişlik N, hassasiyet M
printf "%8.2f\n" 3.14159
3.14
# + işareti: pozitif sayılarda + göster
printf "%+d %+d\n" 42 -42
+42 -42
# hex büyük harf, 0x prefix ile
printf "0x%08X\n" 4294967295
0xFFFFFFFF
05 printf ile döngüde tablo üretmek
printf ve for/while kombinasyonu script'lerde düzenli tablo çıktısı üretmenin en temiz yoludur.
# basit tablo başlığı + ayırıcı
printf "%-20s %8s %10s\n" "Dosya" "Boyut" "İzin"
printf "%-20s %8s %10s\n" "--------------------" "--------" "----------"
# dosya listesi tablosu
while IFS= read -r dosya; do
boyut=$(stat -c "%s" "$dosya")
izin=$(stat -c "%A" "$dosya")
printf "%-20s %8d %10s\n" "$dosya" "$boyut" "$izin"
done < <(find . -maxdepth 1 -type f)
# sayaçlı sıralama (001, 002 ...)
i=1
for isim in "Ali" "Büşra" "Cem"; do
printf "%03d) %s\n" "$i" "$isim"
i=$(( i + 1 ))
done
001) Ali
002) Büşra
003) Cem
# ilerlemé çubuğu simulasyonu
for i in $(seq 1 10); do
printf "\rİşleniyor: %3d%%" $(( i * 10 ))
sleep 0.2
done
printf "\nTamamlandı.\n"
# dosyaya yönlendirme (printf çıktısı dosyaya da gider)
printf "%-10s %s\n" "ad" "soyad" "Ali" "Yılmaz" > rapor.txt
\r imleci satır başına taşır ama satırı silmez. printf "\rYeni metin" ile önceki çıktının üzerine yazılabilir — ilerleme göstergesi için standart teknik.
# CSV üretmek: virgüllü format
printf "%s,%s,%d\n" "ad" "şehir" "yaş"
printf "%s,%s,%d\n" "Ali" "İstanbul" 30
printf "%s,%s,%d\n" "Büşra" "Ankara" 25
ad,şehir,yaş
Ali,İstanbul,30
Büşra,Ankara,25
06 echo tuzakları ve taşınabilirlik
echo'nun farklı ortamlardaki tutarsız davranışları script yazarlarını yanıltır — bunları bilmek önemli.
# Sorun 1: -e davranışı shell'e göre değişir
# bash built-in echo: -e çalışır
# dash (/bin/sh): echo -e çalışmaz, "-e" metni basar
# /bin/echo: sistem bağımlı
# /bin/sh (dash) ile şu çıktı verir:
#!/bin/sh
echo -e "satır1\nsatır2"
-e satır1\nsatır2 ← YANLIŞ, escape yorumlanmadı
# Çözüm: printf kullan
printf "satır1\nsatır2\n"
satır1
satır2
# Sorun 2: - ile başlayan değişken argüman olarak yorumlanır
msg="-n önemli mesaj"
echo $msg # "-n" flag olarak yorumlanır, newline silinir
önemli mesaj ← sonra cursor aynı satırda kalır
# Çözüm: -- ile flag işlemini kapat
echo -- $msg # bash'ta -- çalışmaz! printf kullan
printf "%s\n" "$msg"
-n önemli mesaj
# Sorun 3: xsi (bash'ta $'...' sözdizimi)
# bash'a özgü, taşınabilir değil
echo $'\t Sekme ile başlar' # bash'ta çalışır
# ama sh/dash/zsh'ta farklı davranabilir
# Taşınabilir renk: tput kullan
RED=$(tput setaf 1)
RST=$(tput sgr0)
printf "%sHATA%s: mesaj\n" "$RED" "$RST"
#!/bin/bash ile başlayan script'lerde bash built-in echo kullanılır. #!/bin/sh ile başlayan (POSIX sh) script'lerde echo -e güvenilmez — her zaman printf tercih edin.
# ✓ İnteraktif hızlı debug
echo "$degisken"
# ✓ Script'te string bas
printf "%s\n" "$degisken"
# ✓ Hata mesajı → stderr
printf "HATA: %s\n" "$mesaj" >&2
# ✓ Biçimlendirilmiş sayı
printf "%.2f MB\n" "$boyut"
# ✓ Sıfır dolgulu sayaç
printf "%04d\n" "$sayac"
# ✗ Script'te -e ile escape (taşınabilir değil)
echo -e "satır1\nsatır2"
# ✗ Tırnaksız değişken
echo $degisken
07 Özet ve referans
Hatırlanacaklar
echointeraktif kullanım için,printfscript'ler için tercih edilmeliecho -ebash built-in'de çalışır ama/bin/sh(dash) ile çalışmaz- printf'e fazla argüman verilirse format tekrar uygulanır — liste basmada kullanışlı
%Nssağa hizalar,%-Nssola hizalar,%0Ndsıfır doldurur%.2fiki ondalık basamak,%8.2fsekiz karakter genişliğinde iki basamak- Hata mesajları
>&2ile stderr'e yönlendirilmeli - ANSI renkleri pipe/dosyaya yönlendirilince ham escape baytı olarak çıkar
tput setaf Nile terminfo tabanlı renk: daha taşınabilirprintf "\r"ile ilerleme çubuğu: satır başına gidip üzerine yaz- Değişken
-ile başlayabiliyorsaprintf "%s\n" "$var"kullan
# echo
echo "metin" # newline ile bas
echo -n "metin" # newline ekleme
echo -e "sat1\nsat2" # escape yorumla (bash)
# printf
printf "%s\n" "metin" # string bas
printf "%d\n" 42 # tam sayı
printf "%.2f\n" 3.14 # 2 basamak float
printf "%05d\n" 7 # 00007
printf "%-10s %s\n" "sol" "sağ" # sütun hizala
printf "%s\n" "$mesaj" >&2 # stderr'e
# ANSI
printf "\e[31mKırmızı\e[0m\n"
printf "\e[32mYeşil\e[0m\n"
printf "\e[1;33mKalın Sarı\e[0m\n"
Devam: Kabuk değişkenleri, alias ve history · stdin/stdout/stderr ve pipe