Ders 02 / 24
Yönlendirme
Yönlendirme işleçleri, kesme ile ekleme farkı, tanıtıcı çoğaltma ve sıranın önemi, üzerine yazma tuzakları.
İçindekiler
Önceki ders akışların uçlarının değiştirilebilir olduğunu gösterdi ama değiştirme
gösterimini kuralıyla açıklamadı. 2>/dev/null yazıldığında kabuk tam olarak ne yapar,
> ile >> neden farklıdır, iki akışı tek dosyada toplarken sıra neden önemlidir?
Yönlendirme, kabuğun komutu çalıştırmadan önce yaptığı bir iştir. Komut başlamadan tanıtıcılar bağlanır; komut, uçlarının değiştirildiğini hiç fark etmez. Bu dersin tüm kuralları bu tek cümleden türer.
Kesme ve Ekleme
Standart çıktıyı dosyaya bağlayan iki işleç vardır.
> kesme (truncate) yapar: dosya yoksa yaratılır, varsa içeriği silinir. Yönlendirme
komut çalışmadan uygulandığı için, komut hiçbir şey yazmasa bile dosya boşalır.
echo "birinci" > not.txt echo "ikinci" > not.txt cat not.txt
ikinci
>> ekleme (append) yapar: yazma konumu her seferinde dosyanın sonuna alınır.
echo "birinci" > not.txt echo "ikinci" >> not.txt cat not.txt
birinci ikinci
Kesmenin komuttan bağımsız olması, bir dosyayı boşaltmanın en kısa yolunu verir. :
yerleşik komutu hiçbir şey yapmaz ve hiçbir şey yazmaz; yönlendirme yine de uygulanır:
: > not.txt wc -c not.txt
0 not.txt
Bir kütük dosyasını sıfırlamanın doğru yolu budur. Dosyayı silip yeniden yaratmak yerine içeriğini boşaltmak, dosyayı açık tutan süreçlerin yazmaya devam etmesini sağlar; silinen dosyanın tanıtıcısı geçerli kalır ama yazılanlar hiçbir dizinden erişilemez olur.
Girdi Yönlendirme
< işleci, standart girdiyi bir dosyaya bağlar. Önceki derste görüldüğü gibi bu, dosya
adını argüman olarak vermekle aynı şey değildir: komut yalnızca bir akış görür.
sort < erisim.log | head -2
10.0.0.12 - - [07/Feb/2024:09:12:44 +0000] "GET /index.html HTTP/1.1" 200 5120 10.0.0.12 - - [07/Feb/2024:09:13:02 +0000] "GET /urun/12 HTTP/1.1" 200 8410
Girdi yönlendirmesi dosyayı yalnızca okumaya açar; var olmayan bir dosya verilirse komut hiç çalıştırılmaz ve kabuk hata bildirir.
Tanıtıcı Numarasıyla Yönlendirme
Yönlendirme işleçlerinin önüne yazılan sayı, hangi tanıtıcının bağlanacağını söyler.
Sayı yazılmazsa çıktı yönlendirmelerinde 1, girdi yönlendirmesinde 0 varsayılır.
Dolayısıyla > dosya ile 1> dosya aynıdır.
ls erisim.log yok.txt >var.txt 2>hata.txt
var.txt yalnızca veriyi, hata.txt yalnızca tanı iletisini alır:
erisim.log
ls: yok.txt: No such file or directory
Sayı ile işleç arasında boşluk bulunamaz: 2 > hata.txt yazılırsa kabuk 2 dizgisini
komuta argüman olarak geçirir ve yalnızca standart çıktıyı yönlendirir.
Tanıtıcı Çoğaltma ve Sıra
n>&m gösterimi yönlendirme değil çoğaltmadır (duplication): n numaralı
tanıtıcı, m numaralının o an gösterdiği yeri gösterecek biçimde ayarlanır. Bu bir
bağlantı kopyalamadır; sonradan m değişse bile n eski yerde kalır.
Kural buradan çıkar: yönlendirmeler soldan sağa uygulanır. İki akışı aynı dosyada toplamanın doğru yazımı önce hedefi belirlemek, sonra çoğaltmaktır.
ls erisim.log yok.txt >hepsi.txt 2>&1 cat hepsi.txt
ls: yok.txt: No such file or directory erisim.log
Sıra ters çevrilirse sonuç değişir:
ls erisim.log yok.txt 2>&1 >ayri.txt
Bu çağrıda önce 2, o anki 1’in gösterdiği yere — yani terminale — bağlanır. Sonra
1 dosyaya çevrilir, ama 2 terminalde kalmıştır. Terminale şu düşer:
ls: yok.txt: No such file or directory
ayri.txt ise yalnızca veriyi alır:
erisim.log
Bu, yönlendirmenin en sık yapılan hatasıdır. Yazılışları birbirine benzeyen iki gösterimden biri “her şeyi dosyaya”, diğeri “hataları eski yere, veriyi dosyaya” anlamına gelir.
Bash, ilk durumun kısaltması olarak &> dosya yazımını da tanır. Kısa olmakla birlikte
POSIX kabuk dilinde tanımlı değildir; taşınabilir olması gereken betiklerde
>dosya 2>&1 yazımı tercih edilir. Aynı biçimde &>> ekleme yapar.
İki Yere Birden Yazmak
Yönlendirme tek hedef alır. Çıktının hem dosyaya kaydedilmesi hem de bir sonraki komuta
akması gerektiğinde tee kullanılır: standart girdisinden okuduğunu hem verilen
dosyalara hem de standart çıktısına yazar.
head -2 erisim.log | tee ilk-iki.txt | wc -l
2
ilk-iki.txt içeriği:
10.0.0.12 - - [07/Feb/2024:09:12:44 +0000] "GET /index.html HTTP/1.1" 200 5120 10.0.0.31 - - [07/Feb/2024:09:12:51 +0000] "GET /statik/stil.css HTTP/1.1" 200 2048
tee -a dosyayı keserek değil ekleyerek yazar. Kurs sonunda yazılacak raporlama
betiğinde tee, hem ekrana hem kütüğe yazmak için kullanılacak.
Üzerine Yazma Koruması
> işlecinin var olan dosyayı sessizce silmesi, elle yazılan komutlarda veri kaybının
yaygın nedenidir. noclobber seçeneği bu davranışı kapatır:
set -o noclobber echo "a" > n.txt # dosya yok, yaratılır echo "b" > n.txt # dosya var, reddedilir
bash: n.txt: cannot overwrite existing file
Koruma açıkken bilinçli üzerine yazma >| ile yapılır:
echo "c" >| n.txt cat n.txt
c
noclobber etkileşimli oturum için yararlıdır; betiklerde ise güvenilmez bir dayanaktır,
çünkü betiği çalıştıran kabuğun ayarına bağlıdır. Betikte üzerine yazmayı engellemek
istiyorsanız dosyanın varlığını açıkça sınayın — koşul sınamaları Betik Yapısı konusunda
ele alınacak.
Aynı Dosyayı Okuyup Yazmak
Yönlendirmenin komuttan önce uygulanması, tek bir kuralı kaçınılmaz kılar: bir komutun girdi dosyası ile çıktı dosyası aynı olamaz.
printf 'c\nb\na\n' > kucuk.txt sort kucuk.txt > kucuk.txt wc -c kucuk.txt
0 kucuk.txt
Dosya boşaldı. Kabuk kucuk.txt dosyasını kesti, sonra sort çalıştı ve okuyacak
hiçbir şey bulamadı. Veri geri getirilemez.
Bu yüzden yerinde dönüştürme yapan araçlar (akış editörünün -i seçeneği gibi) dosyayı
doğrudan değiştirmez; geçici dosyaya yazıp sonunda yer değiştirir. Aynı işi elle yapmak
gerektiğinde izlenecek desen şudur:
sort kucuk.txt > kucuk.yeni && mv kucuk.yeni kucuk.txt
&& işleci, soldaki komut başarılı bitmediyse sağdakini çalıştırmaz; böylece sort
hata verdiğinde özgün dosya yerinde kalır. Bu işlecin tam anlamı bu konunun son dersinde
tanımlanacak.
Betiğin Tümünü Yönlendirmek
exec yerleşik komutu, komut adı verilmeden yalnızca yönlendirmelerle çağrılırsa,
yönlendirmeleri kabuğun kendisine uygular. O noktadan sonraki tüm komutlar yeni
uçları kullanır.
exec 3>&1 1>kayit.txt # 1'in eski yerini 3'te sakla, 1'i dosyaya çevir echo "dosyaya" exec 1>&3 3>&- # eski yeri geri yükle, 3'ü kapat echo "ekrana"
Terminale yalnızca ikinci satır düşer:
ekrana
kayit.txt içeriği:
dosyaya
3>&- gösterimi tanıtıcıyı kapatır. Üç ve üzeri numaralı tanıtıcılar bu tür geçici
saklama için serbesttir; kabuk onlara anlam yüklemez. Bu desen, bir betiğin tüm
çıktısını kütüğe alıp yalnızca özeti terminale döndürmek için kullanılır ve kursun
sonunda zamanlanmış görev yazarken işe yarayacak.
Özet
- Yönlendirme komut çalışmadan önce uygulanır; komut, tanıtıcılarının nereye bağlandığını bilmez.
>hedefi keser,>>sonuna ekler; kesme komuttan bağımsız olduğu için: > dosyabir dosyayı boşaltır.- İşlecin önündeki sayı hangi tanıtıcının bağlanacağını belirler;
n>&mçoğaltmadır ve yönlendirmeler soldan sağa uygulandığı için>dosya 2>&1ile2>&1 >dosyafarklı anlamlara gelir. - Tek çıktının iki hedefe gitmesi gerektiğinde
teekullanılır. - Bir komutun girdi ve çıktı dosyası aynı olamaz; doğru desen geçici dosyaya yazıp yer değiştirmektir.
Sonraki Adım
Yönlendirme, akışın ucuna bir dosya koyar. Asıl bileşim gücü ise ucuna başka bir komut konduğunda ortaya çıkar. Sonraki ders boru hattını ele alır: komutların eşzamanlı çalışması, verinin arada dosyaya uğramadan akması ve bu düzenin getirdiği iki tuzak — zincirin çıkış kodu ve alt kabukta kaybolan değişkenler.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.