top of page

Basit Kabuk Komut Dosyası Oluşturma-3

  • Yazarın fotoğrafı: Huseyin Şahan
    Huseyin Şahan
  • 1 Nis
  • 6 dakikada okunur

Bu blog yazımızda kabuk üzerinde nasıl matematiksel işlemler yapabileceğimizi ve ardından kabuk dosyasındaki komutları çalıştırdıktan sonra nasıl çıkış yapabileceğimizi göreceğiz.


expr Komutu


expr komutu Bourne kabuğu'nın başlangıç zamanlarında, kabuk komutlarıyla sayısal ifadeleri değerlendirmek için bir komuttur. Bu komut basit aritmetik işlemleri gerçekleştirebilir ancak kullanımı biraz zordur. Aşağıda basit bir kullanımını görebilirsiniz.

darkside@debian:~$ expr 1 + 5

Burada komutun kullanımı neden biraz zor ve hantal açıklamaya çalışalım. Öncelikle expr komutu ile işlemleri yapabilmek için operatörler arasında boşluk olmalıdır. Eğer boşluk olmazsa işlem hata verecektir ve sonucu göstermeyecektir.


Expr komutunun bir diğer dezavantajı ise sadece tamsayılarla çalışıyor olmasıdır. Aşağıdaki örnek bu nedenle çalışmayacaktır.

darkside@debian:~$ expr 1.2 + 1.3

İşlem aşağıdaki gibi tam sayı olmayan argüman hatası verecektir.

ree

Bu komut sadece tamsayılar üzerinde değil string ifadeleri üzerinde de işlem yapar.


String Uzunluğunu Hesaplama
darkside@debian:~$ expr length "Merhaba"

expr komutunu kullanarak bir string'in uzunluğunu bulabilirsiniz. Bunun için length fonksiyonu kullanılır:


String Karakterlerini Elde Etme (Substring)
darkside@debian:~$ expr substr "Merhaba" 1 3

Bir string içinden belirli bir karakteri veya alt string'i almak için expr komutunda substr fonksiyonunu kullanabilirsiniz.


String İçinde Arama
darkside@debian:~$ expr index "Merhaba" "r"

Bu komut, "Merhaba" string'inde "r" karakterinin bulunduğu ilk konumu döndürür (3. pozisyon). Eğer aradığınız karakter veya alt string bulunmazsa, sonuç 0 olur


String Birleştirme
darkside@debian:~$ expr "Merhaba" : "Mer"

Bu komut, "Merhaba" string'inin "Mer" alt string'ine uyup uymadığını kontrol eder. Burada : operatörü ile eşleştirme yapılır.


String Eşitlik Kontrolü
darkside@debian:~$ expr "Merhaba" = "Merhaba"

Bu komut, "Merhaba" ile "Merhaba" string'lerinin eşit olduğunu doğrular. Eğer eşitlerse 1 döner, değilse 0 döner.


gibi komutlarla expr komutunu kullanabilirsiniz. Tüm komutlar aşağıda verilmiştir.


ARG1 & ARG2

Eğer her iki argüman da null veya sıfır değilse ARG1'i döndürür, aksi takdirde 0 döndürür.

ARG1 < ARG2

Eğer ARG1, ARG2'den küçükse 1 döndürür, aksi takdirde 0 döndürür.

ARG1 <= ARG2

Eğer ARG1, ARG2'den küçük veya eşitse 1 döndürür, aksi takdirde 0 döndürü

ARG1 = ARG2

Eğer ARG1 ile ARG2 eşitse 1 döndürür, aksi takdirde 0 döndürür.

ARG1 != ARG2

Eğer ARG1 ile ARG2 eşit değilse 1 döndürür, aksi takdirde 0 döndürür.

ARG1 >= ARG2

Eğer ARG1, ARG2'den büyük veya eşitse 1 döndürür, aksi takdirde 0 döndürür.

ARG1 > ARG2

Eğer ARG1, ARG2'den büyükse 1 döndürür, aksi takdirde 0 döndürür.

ARG1 + ARG2

ARG1 ve ARG2'nin aritmetik toplamını döndürür.

ARG1 - ARG2

ARG1 ve ARG2'nin aritmetik farkını döndürür.

ARG1 * ARG2

ARG1 ve ARG2'nin aritmetik çarpımını döndürür.

ARG1 / ARG2

ARG1'i ARG2'ye bölüp aritmetik bölümünü döndürür.

ARG1 % ARG2

ARG1'i ARG2'ye böldüğünde kalan değeri döndürür (aritmetik modül).

STRING : REGEXP

Eğer REGEXP, STRING içinde bir desenle eşleşirse, eşleşen kısmı döndürür.

match STRING REGEXP

Eğer REGEXP, STRING içinde bir desenle eşleşirse, eşleşen kısmı döndürür.

substr STRING POS LENGTH

STRING'in POS konumundan başlayarak LENGTH uzunluğunda bir alt diziyi döndürür (başlangıç 1'den başlar).

index STRING CHARS

STRING içinde CHARS'ın bulunduğu ilk pozisyonu döndürür; eğer bulunmazsa 0 döndürür.

length STRING

STRING'in uzunluğunu (karakter sayısını) döndürür.

+ TOKEN

TOKEN'ı bir string olarak yorumlar, hatta bir anahtar kelime olsa bile.

(EXPRESSION)

EXPRESSION ifadesinin değerini döndürür.

Ancak burada çarpma işlemini yaparken dikkatli olmak gerekir. * (Yıldız) karakteri kabukta wilcard karakteri olarak algılanacağı için aşağıdaki komu hatalı olacaktır.

darkside@debian:~$ expr 5 * 2
ree

Bu hatayı aşmanın yolu ters eğik çizgi ile kullanmaktır.

darkside@debian:~$ expr 5 \* 2

Matematiksel İşlemler İçin Kare Parantez Kullanma


Matematiksel işlemleri yapmak için daha kolay yöntem mevcuttur. Kabuk geriye dönük uyumluluğu korumak için hala expr komutunu çalıştırabilir. ancak daha modern bir kullanım dolar işareti($) ve köşeli parantez( ] ) kullanmaktır. Aşağıda temel matematiksel işlemler için örnek kullanımlar ve bir komut dosyası verilmiştir.

darkside@debian:~$ var=$[1 + 5]
darkside@debian:~$ echo $var

veya çarpma işlemi yapabiliriz.

darkside@debian:~$ var2=$[2 * 5]
darkside@debian:~$ echo $var2

Bunu aşağıdaki gibi bir betik dosyasında kullanalım.

#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4

Eğer dosyayı çalıştırma izniniz yoksa ekleyin:

darkside@debian:~/scriptfiles$ chmod u+x betikdosyası4

Ardından betiğimizi çalıştıralım:

darkside@debian:~/scriptfiles$ ./betikdosyası4

Köşeli parantez yöntemi iexpr komutuna göre daha anlaşılır sözdizimi sağlar. Ancak yine bazı sınırlamalar vardır. Örneğin köşeli parantez yöntemi yalnızca tamsayılarla çalışır. Örneğin bölme işlemi yaparken sonuş kesrli çıksa bile kesilir ve tam kısım gösterilir. Aşağıdaki örnek dosyayı kayededin ve çalıştırın:

#!/bin/bash
var1=100
var2=40
var3=$[$var1 / $var2]
echo The final result is $var3

Sonuç kesirli çıkıyor olmasına rağmen Bash kabuğu bunu 2 olarak gösterecektir. Veya aşağıdaki komut dosyası ondalıklı sayılarla işlem yapmayacak ve hata verecektir.

#!/bin/bash
var1=10.24
var2=2
var3=$[$var1 / $var2]
echo The final result is $var3

Ondalıklı Sayı Hatası Çözümü


Kabukta köşeli parantez yöntemini kullanırken kabuğun ondalıklı sayıları anlamayacağını ve hatalı sonuçlar döndüreceğini söylemiştik. Ancak bu yöntemi aşmanın bir yolu bulunmaktadır. En yaygın çözüm bc komutunu kullanmaktır.


bc komutu bir programlama dili gibidir ve bu dil ile ondalıklı sayı hesabı yapabilirsiniz.

bc komutunun temel özellikleri aşağıda verilmiştir.


  • Sayılar: Hem tam sayılar (integer) hem de ondalıklı sayılarla işlem yapabilir.

  • Değişkenler: Hem basit değişkenler hem de diziler (arrays) kullanılabilir.

  • Yorumlar: # ile başlayan satırlar ve C dilindeki gibi /* */ yorumları kullanılabilir.

  • İfadeler ve Programlama Komutları: Matematiksel ifadeler ve temel programlama komutları (if-then gibi) çalıştırılabilir.

  • Fonksiyonlar: Kendi fonksiyonlarınızı tanımlayabilirsiniz.


bc komutu ile hesaplama aracını başlatın. Bunu yapmak için:

darkside@debian:~$ bc

Şeklinde başlatabilirsiniz. Araç aşağıdaki gibi görünecektir.

ree

Aşağıda basit kullanımı gösterilmiştir.

12 * 4
48
3.45 * (3 + 5)
27.60
quit

Burada quit komutu veya ctrl + D tuş kombinasyonu ile araçtan çıkış yapabilirsiniz.


Ondalık Hassasiyetini Ayarlamak

bc komutunun içindeki scale değişkeni, ondalıklı sayıların hassasiyetini belirler. Varsayılan olarak scale=0 (tam sayılarla işlem) olur, ancak bunu ayarlayarak daha fazla ondalıklı basamağa sahip sonuçlar alabilirsiniz.

darkside@debian:~$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit

İlk işlemde scale=0 değerine sahip olduğu için hassasiyet 0 olacaktır. Ardından sacel=4 değerine sahip olduğu için .6880 değerine sahip olacaktır. Bu noktdan sonra gösterilecek karakter sayısıdır.


Bu komut ile değişken oluşturup yazdırabiliriz.

$ bc -q
var1=10
var1 * 4
40
var2 = var1 / 5
print var2
2
quit

Burada değişkenin değerini print ile yazdırabilirsiniz.


Peki burada asıl soru bc komutunu kabuk betiklerinde nasıl kullanabiliriz ? Bunu yapmanın bir yolu echo ile komutun çıktısını bc aracına yönlendirmektir. Bu sayede bc aracı bize komutun çıktısını verecektir.

#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1

Burada dikkat edin bc aracına komutları ; ile bildirin. Burada scale değeri 4 olarak ayarlanmış ve yapılmak istenenn işlem verilmiştir.


Değişkenlerle nasıl çalışabileceğinizle alakalı başka bir örnek verilmiştir.

#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3

gbi ibetik dosyalarını kullanarak işlem yapabilirsiniz. Ancak her zaman tek bir işlem yapmayabilirsiniz. Aşağıda birden fazla işlemi nasıl yapabileceğiniz verilmiştir.

#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5

Burada EOF ve << işaretini kullanarak bc aracına birden fazla parametreyi ilettik ve en son EOF yazarak girdi sonunu belirttik.


Betik Dosyaları Çıkış Durumları

Her komut bir çıkış durumu döndürür. Başarılı bir durumda çıkış değeri 0 olur eğer hatalı bir durum olursa bu durumda 0'dan farklı bir değer döndürür.

Aşağıda birkabukta komut durumlarını inceleyebiliriz.

darkside@debian:~/scriptfiles$ date
Sal 01 Nis 2025 18:46:34 +03
darkside@debian:~/scriptfiles$ echo $?
0

Burada $? ile komutun hangi durumda çıkacağını belirtiyoruz. Ancak burada yanlış bir komut çalıştırmayı deneyelim.

darkside@debian:~/scriptfiles$ skjhsad
bash: skjhsad: komut yok
darkside@debian:~/scriptfiles$ echo $?
127

Görüldüğü gibi çıkış durumu 127 değerine sahip. Bu çıkış durumları için aşağıdaki tabloyu inceleyebilirsiniz.

Kod

Açıklama

0

Komut başarıyla tamamlandı

1

Genel bilinmeyen hata

2

Shell komutunun yanlış kullanımı

126

Komut çalıştırılamaz

127

Komut bulunamadı

128

Geçersiz çıkış argümanı

128+x

Linux sinyali ile fatal hata (x, sinyal numarasını belirtir)

130

Ctrl+C ile komut sonlandırıldı



255

Çıkış durumu aralığı dışı

Örneğin çalıştırma iznimiz olmayan dosyayı çalıştırmaya çalışınca 126 çıkış değerini verecektir.

darkside@debian:~/scriptfiles$ ./betikdosyası4
bash: ./betikdosyası4: Erişim engellendi
darkside@debian:~/scriptfiles$ echo $?
126

Örneğin yanlış bir parametre sağlarsanız çıkış durumu 1 olarak dönebilir.

darkside@debian:~/scriptfiles$ date %t
date: geçersiz tarih `%t'
darkside@debian:~/scriptfiles$ echo $?
1

Bir betik varsayılan olarak çıkış durumu döndürür. Ancak eğer istediğiniz bir çıkış değeri döndürmek istiyorsanız exit komutunu kullanabilirsiniz.

#!/bin/bash
# testing the exit status
var1=10
var2=30
var3=$[$var1 + $var2]
echo The answer is $var3
exit 5

Çıkış durumu 5 olarak belirlenir.


Çıkış durumu 0-255 arası değerler alabilir. Eğer daha büyük değerler verilirse bu değer 256 ile bölünür ve kalan değer çıkış durumu olarak belirlenir.

#!/bin/bash
# testing the exit status
var1=10
var2=30
var3=$[$var1 * $var2]
echo The value is $var3
exit $var3

Burada çıkş değeri 300 sayısının 256 ile bölümünden kalan değer yani 44 olacaktır.


Özetleyecek olursak:

  • Exit status komutun başarı durumunu veya hata durumunu belirtir.

  • Çıkış durumu 0 başarılı komutları, 1-255 arasındaki değerler ise hataları gösterir.

  • exit komutuyla betiğin çıkış durumunu belirleyebilirsiniz.

  • Çıkış durumu 256'dan büyük olursa, modulo 256 hesaplanarak çıkış durumu belirlenir.


Bu blog yazımızda matematiksel işlemleri gerçekleştirmek için expr ve köşeli parantez yöntemlerini ele aldık. Bu yöntemler ondalık sayılarla çalışamadığı için bc komutu ile bu sorunu çözdük ve ardından betik dosyalarında çıkış durumlarını ve ne anlama geldiklerini ele aldık.


Bir sonraki blog yazımızda görüşmek üzere...

Comments


bottom of page