Ders 04 / 24
Burada Belge ve Burada Dizgi
Betiğe gömülü girdi, sonlandırıcının alıntılanmasının genişletmeye etkisi, girinti kaldırma ve tek satırlık girdi gösterimi.
İçindekiler
Önceki üç ders girdinin iki kaynağını gösterdi: klavye ve dosya. Betikler üçüncü bir kaynağa daha ihtiyaç duyar — betiğin kendi metnine gömülü sabit içerik. Yapılandırma şablonu, çok satırlı kullanım iletisi, sınama verisi ve veritabanı sorgusu bu sınıfa girer.
Bu içeriği ayrı bir dosyada tutmak, betiği tek başına taşınamaz kılar. Her satırı ayrı
echo ile yazmak ise satır sonlarını, tırnakları ve boşlukları elle yönetmeyi gerektirir.
Kabuk bu iş için iki gösterim tanımlar.
Burada Belge
Burada belge (here document), << işlecinden sonra bir sonlandırıcı yazılarak
başlar; sonlandırıcının tek başına geçtiği satıra kadarki metin, komutun standart
girdisi olur.
kod=404 cat <<SON Aranan kod: $kod SON
Aranan kod: 404
Sonlandırıcı adı serbesttir; içerikte geçmeyecek bir dizi seçilir. EOF yaygın bir
seçimdir, ama zorunlu değildir — bu kursta SON kullanılacak.
İki kural katıdır. Sonlandırıcı satırında ondan başka hiçbir karakter bulunamaz; sondaki tek bir boşluk bile satırı sonlandırıcı olmaktan çıkarır ve kabuk dosya sonuna kadar okumaya devam ederek hata verir. İkincisi, sonlandırıcı satırı girintili olamaz — bunun bir istisnası aşağıda ele alınıyor.
Genişletme ve Sonlandırıcının Alıntılanması
Burada belge içeriği, öntanımlı olarak çift tırnak içindeymiş gibi işlenir: değişken genişletme, komut yerine koyma ve aritmetik genişletme uygulanır.
ad="rapor" cat <<SON Kutuk: $ad.log Satir sayisi: $(grep -c '' erisim.log) Aritmetik: 5 * 3 = $((5 * 3)) SON
Kutuk: rapor.log Satir sayisi: 30 Aritmetik: 5 * 3 = 15
Sonlandırıcı alıntılanırsa hiçbir genişletme yapılmaz; metin harfi harfine geçer. Alıntılama tek tırnak, çift tırnak veya ters bölü ile yapılabilir; üçü de aynı sonucu verir.
cat <<'SON' Kutuk: $ad.log Komut: $(pwd) Aritmetik: $((5 * 3)) SON
Kutuk: $ad.log Komut: $(pwd) Aritmetik: $((5 * 3))
Bu ayrım yazım süsü değil, doğruluk koşuludur. Bir betiğe başka bir betiğin kaynak kodunu,
bir kabuk yapılandırmasını veya $ içeren herhangi bir şablonu gömerken sonlandırıcı
alıntılanmazsa, gömülü metindeki $ işaretleri dış betikte genişletilir ve içerik sessizce
bozulur. Kural olarak: genişletme bilinçli olarak isteniyorsa sonlandırıcı açık
bırakılır, aksi hâlde alıntılanır.
Girinti Kaldırma
Burada belge, bir if veya for gövdesinin içindeyken çevresindeki kodun girintisine
uymaz; içerik harfi harfine aktarıldığı için girinti de metne girer. <<- biçimi bu
sorunu kısmen çözer: içerik satırlarının ve sonlandırıcı satırının başındaki sekme
karakterlerini siler.
if true; then cat <<-SON girintili satir ikinci satir SON fi
girintili satir ikinci satir
Kısıt açıktır: yalnızca sekme karakteri silinir, boşluk silinmez. Boşlukla girintileyen
bir dosyada <<- hiçbir işe yaramaz. Bu, kabuk dilinin taşınabilir tutulmuş ama
kullanışsız kalmış köşelerinden biridir; yazım kurallarınız boşluk girintisi
gerektiriyorsa burada belgeyi girintisiz bırakmak daha az sürprizlidir.
Burada Dizgi
Burada dizgi (here string), tek satırlık girdi için kısaltmadır. <<< işlecinin
sağındaki değer, sonuna bir satır sonu eklenerek komutun standart girdisi olur.
ad="rapor" tr 'a-z' 'A-Z' <<< "$ad hazir"
RAPOR HAZIR
Eklenen satır sonu gerçektir ve sayılır:
wc -c <<< "abc" printf '%s' "abc" | wc -c
4
3
Bu fark, uzunluk sayan veya baytı baytına karşılaştıran işlerde önemlidir. Satır sonu
istemiyorsanız burada dizgi değil, printf ile boru hattı kullanın.
Burada dizginin en yaygın kullanımı, bir dizgiyi alanlarına ayırmaktır:
read -r adres kod <<< "10.0.0.12 200" echo "adres=$adres kod=$kod"
adres=10.0.0.12 kod=200
Aynı işi boru hattıyla yapmak, önceki dersteki alt kabuk tuzağına düşerdi:
echo ... | read yazımında read alt kabukta çalışır ve atadığı değişkenler kaybolur. Burada dizgi
yönlendirmedir, boru değildir; komut ana kabukta kalır. <<< bash eklentisidir, POSIX
kabuk dilinde yoktur.
Boru Hattında ve Yönlendirmeyle
Burada belge de sıradan bir girdi yönlendirmesidir; komutun geri kalan yönlendirmeleriyle ve boru hattıyla birlikte kullanılabilir. Yönlendirmeler komut satırının sonunda toplanır, içerik ise komutu izleyen satırlardan başlar:
sort <<'SON' | head -2 gamma alpha beta SON
alpha beta
Çıktının hedefe yazılması da aynı satırda belirtilir. Bu, sabit içeriği dosyaya dökmenin en doğrudan yoludur:
cat > mini.log <<'SON' 10.0.0.1 GET /a 200 10.0.0.2 GET /b 404 SON
wc -l mini.log
2 mini.log
Kütüğü Yeniden Üretmek
Bu kursun erisim.log dosyası bir dış kaynaktan indirilmez; betikle üretilir. Böylece
her okur aynı veriyle çalışır ve sonuçlar birebir karşılaştırılabilir olur.
Aşağıdaki veri-uret.sh betiği kütüğü sıfırdan yazar. Sonlandırıcı alıntılanmıştır:
içerikte $ geçmese bile, veri metnini genişletmeye açık bırakmamak doğru varsayılandır.
cat > veri-uret.sh <<'BETIK_SONU' cat > erisim.log <<'SON' 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 SON BETIK_SONU
Dıştaki sonlandırıcı (BETIK_SONU) ile içteki (SON) farklı seçilmiştir. Aynı olsalardı
dış belge ilk SON satırında biterdi ve geri kalan metin komut olarak yorumlanırdı. İç
içe burada belge yazarken sonlandırıcıların ayrı olması zorunludur.
Yukarıdaki parça, dersin başındaki otuz satırın ilk ikisini içerir; tam veri
kümesi Standart Girdi, Çıktı ve Hata dersinde verilmişti. Kendi veri-uret.sh
dosyanızı otuz satırın tamamıyla oluşturun; sonraki derslerde kütük bozulduğunda tek
komutla geri getirilebilir olacak.
Ne Zaman Hangisi
Üç gösterim aynı işi farklı ölçeklerde yapar:
| Gösterim | Girdi | Genişletme | Tipik kullanım |
|---|---|---|---|
<< SON |
çok satırlı | uygulanır | şablon, biçimlendirilmiş rapor başlığı |
<< 'SON' |
çok satırlı | uygulanmaz | gömülü kaynak kod, sabit veri |
<<< |
tek satırlı | uygulanır | dizgiyi alanlara ayırma, tek satır süzme |
Dördüncü bir seçenek olarak printf ile boru hattı her zaman kullanılabilir ve
tamamen taşınabilirdir; karşılığında satır sonlarının elle yönetilmesini ister.
Özet
- Burada belge,
<<ile başlar ve sonlandırıcının tek başına geçtiği satıra kadarki metni komutun standart girdisi yapar. - Sonlandırıcı alıntılanmazsa içerik çift tırnak kuralıyla genişletilir; alıntılanırsa harfi harfine geçer. Gömülü kaynak kodda alıntılamak zorunludur.
<<-biçimi yalnızca sekme girintisini kaldırır; boşluk girintisine etkisi yoktur.- Burada dizgi tek satırlık girdi verir ve sonuna satır sonu ekler; boru hattının aksine komutu alt kabuğa itmez.
- İç içe burada belgelerde sonlandırıcılar farklı seçilmelidir.
Sonraki Adım
Bu konudaki tüm örneklerde komutların başarılı olduğu varsayıldı. Oysa grep eşleşme
bulamadığında, cut dosyayı açamadığında ya da sort disk alanı bulamadığında bir
sonuç bildirir. Sonraki ders bu bildirimi — çıkış kodunu — tanımlar: sıfırın neden başarı
demek olduğunu, && ve || işleçlerinin bu koda nasıl bağlandığını ve kabuğun kendi
ayırdığı kod aralıklarını ele alır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.