Delphi Can

Orjinalini görmek için tıklayınız: Bash Kabuk Programlama
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Bash Kabuk Programlama Dersleri 1 (Giriş)
   Merhaba.
 Bash Kabuk programlama derslerine başlıyoruz.Dersin hedef kitlesi Linux hakkında temel düzeyde bilgisi olan programlama bilen kişilerdir.Bu yüzden Kabuk,Kernel,Donanım gibi konuları anlatmayacağım,ayrıca kabuk çeşitlerinden de bahsetmeyeceğim.Bu konularda bilgi eksiği olanlar kısa bir araştırmayla yeterli bilgiye ulaşacaklardır.Bizim burada temel alacağımız Bash (Bourne Again Shell) kabuğudur fakat kabuklar birbirine benzemektedir.Özellikle Bash ve sh kabukları oldukça yakındır birbirine.Burada öğreneceğimiz bilgileri başka kabuklarda da kullanmak zor olmayacaktır.


 Bash Kabuk programlama, bir programlama dili kadar kuvvetli olmasa da oldukça yeteneklidir.Sistemin ayağa kaldırılmasından,dosya,disk işlemleri, bir çok programın setup'ına kadar geniş bir kullanımı vardır.Üstelik bir programlama dilinde olan değişkenler,diziler,karar yapıları,döngüler,fonksiyonlar gibi bir çok yapı mevcuttur.
 Bash kabuğu herhangi bir  Linux dağıtımı altında kullanılabildiği gibi openssh temelinde mobil aygıtlarda,putty programıyla windowsta kullanılabilmektedir.Ayrıca Windows 10 öncesinde cygwin kütüphanesiyle windows 10'da Ubuntu on Windows özelliği aktifleştirilerek windows üzerinde de  kullanılabilmektedir.Üstelik Bash kabuğu dos kabuğuna göre çok daha yeteneklidir.


   Biz bu derslerde  Bash Betiğine (shell script) bash programı diyeceğiz.Bir bash programının tepesinde #!/bin/bash  ifadesi yer almalıdır.Bu çalışacak programın bash kabuğunda çalışacağını gösterir.Varsayılan kabuk bash ise bu ifade eksik olsa da sorun olmayacaktır ama varsayılan bash olmadığında sorun olacağı için bash programının en üstünde yer almalıdır çünkü başka bir kabuk altında bu ibare görüldüğünde sistemde bash kabuğu varsa program(script) bash kabuğu altında çalıştırılacaktır.Terminele "which bash" yazdığınızda aynı çıktıyı alırsıınız. 


  Linux'ta "touch <dosya_adi>" komutu dosya oluşurmak için kullanılır.touch komutuyla dosya oluşturup herhangi bir text editörüyle dosyayı açabilceğiniz gbi bir çok yöntemle script dosyası oluşturabilirsiniz.Terminal üzerinde vi yada nano editörü kullanılabilir ki ben nano'yu kullanacağım.nano  <dosya_adi>  diyerek daha sonra  ctrl x  ve  E tuşuna basarak dosyayı kaydederek de aynı sonucu alabileceğiniz gibi aşağıdaki yöntemleri de kullanabilirsiniz.
  which bash > dosya_adi.sh
. echo  '#!/bin/bash'  > dosya_adi.sh
  cat  > dosya_adi.sh  #enter tuşuna bastıktan sonra
'#!/bin/bash'
 vs. bir çok yöntemle yazmaya başlanabilir
.
Bash kabuğunda # başlayan satırlar yorum satırıdır dikkate alınmaz.

Bir bash programı iki şekilde çalıştırılabilir.Birincisi terminalde dosyanın bulunduğu dizinde "chmod +x dosya_adi.sh"  komutundan sonra ./dosya_adi.sh şeklinde çalışırılır ki C'de yada başka bir dilde yazdığımız programı da aynı şekilde çalıştırırız.Ayrıca dosyamızın bulunduğu dizin PATH değişkeni içerisinde tanımlıysa doğrudan dosya_adi.sh şeklinde de çalıştırabiliriz.İkincisi terminalde yine dosyanın bulunduğu dizinde "bash dosya_adi.sh" şeklinde de çalıştırılabiliriz.


 Başlamadan birkaç hatırlatma
1. Terminalde dosya adlarının arasında boşluk olmasını istiyorsanız "\" işaretini boşluktan önce kullanınız.
2. Dosya yada komut adlarının kabuk tarafından tamamlanması için tab tuşuna basınız.
3. Her komut aslında bir programdır./bin,/sbin/,/usr/bin/ dizinlerini incelerseniz görebilirsiniz.
4. Linuxta dosyanın uzantısı olmak zorunda değildir.Uzantısız olarak oluşturduğunuz dosya  varsayılan olarak  text tabanlıdır.
5 ."~" ifadesi Kullanıcının home dizinini gösterir. ~/.bashrc dosyası, kullanıcının açtığı kabuk öncelikle bu dosyayı okur.Bu dosya üzerinde kendimizce değişiklikler  yapabiliriz.PS1 değişşkeni üzerinde oynama yaparak giriş satırımızı değiştirebiliriz."alias" komutuyla kendimizce komutlar oluşturabiliriz.Örneğin alias cls="clear" tanımlamasıyla terminalde dosdaki  "cls " komutu gibi ekranı temizleyebiliriz.Yada bu tanımlamaların hepsini ayrı bir dosyada yapıp .bashrc  içine "source dosya_adi.sh" ifadesini yazabiliriz
6. ">", ">>" ifadeleri ekrana verilen çıktıyı bir dosyaya yönlendirmemizi sağlar ">" ifadesi dosyayı sıfırdan yazar," >>" ifadesi
dosyanın sonuna ekleme yapmamızı sağlar.
7.Giriş satırındaki "$" işareti  normal kullanıcıda olduğunuzu,"#" işareti root kullanıcıda olduğunuzu gösterir..Mecbur kalmadıkça root kullanıcıya geçmeyiniz,ihtiyaç duyduğunuzda komutunuzun başına  "sudo" ifadesini getirerek komutunuzu root hakkıyla kullanabilirsiniz.
8.Linux'un "cd,ls,cat,touch,mkdir,pwd,chmod,cp,mv,rm..." gibi temel komutları bildiğiniz varsayılmaktadır.Eğer bilmiyorsanız.Google'da Temel Linux komutları diyerek yapacağınız basit bir aramayla yeterli bilgiye ulaşabilirsiniz.
 


GİRİŞ
 echo Komutu:
1.Ekrana yada istediğimiz bir dosyaya çıktı vermemizi sağlar.
örnek 1:
ders1Ornek1.sh

  
#!/bin/bash
echo "Bash Programlıyorum"

2. echo komutunu "" ifadesi ile çağırırsak içindeki değişkenleri dikkate alır,'' ifadesi ile çağırırsak tamamını text olarak kabul eder.
örnek 2:
ders1Ornek2.sh

 
#!/bin/bash
degisken1=55
echo " Bu değişken=$degisken1" #değişkenlerin değeri $ ifadesiyle alınır.
echo 'Bu değişken= $degisken1'
 
3. İlerde fonksiyonları göreceğiz ama programlama bilgisine dayanarak şunu belirtebiliriz.Bash'ın fonksiyonlar için  bir return bildirimi olmasına rağmen , onunla belirtebileceğiniz tek şey,
fonksiyonun kendi çıkış durumudur (0 ile 255 arasında bir değer, 0 "başarı" anlamına gelir).Bu yüzden dönüş değerini echo ile döndürebiliriz.



örnek 3:
ders1Ornek3.sh

 
#!/bin/bash
carp()
{
a=$1 #birinci parametre
b=$2 #ikinci parametre
let c=a*b
echo  $c
}
 echo $(carp $1 $2)


./ders1Ornek3.sh 25 3 şeklinde  çağırdığınızda 75 sonucunu görürsünüz.


Gelecek ders "Değişkenler" konusunda görüşmek üzere...

 DERS 2

Başlamadan birkaç önbilgi

1) “. “   ifadesi başka bir bash dosyasını import etmemizi sağlar

2) “export” ifadesi değişkenin çalıştığı kabuk ve alt kabuklarda tanınmasını sağlar,bir nevi değişkeni globalleştirir.Bash’te bir scripti çalıştırdığımızda yeni bir kabuk açılır program çalışır ve kabuk kapanır.Dolayısıyla  programı çalıştırdığımız kabuk, komutu başlattığımız kabuğun alt kabuğudur, ayrıntı için fork fonksiyonunu inceleyebilirsiniz.Ama unutmayın,export ifadesi  ana kabukta kullanılmış ise alt kabuklar değişkeni tanır; ama tersi durumda alt kabukta kullanıldığı bir değişkeni ana kabuk yada diğer kardeş alt kabuklar tanımaz.

3) ”eval” komutu verilen string bir ifadenin kabukta çalışmasını sağlar.Ör: eval “a=5 && echo $a” ekranda 5 yazar.Kabukta tekrar echo $a yazdığımızda değişkenimiz ordadır ve yine 5 yazar. 

Değişkenler

Bildiğimiz gibi değişkenler veri tutmaya yarar, dolayısıyla da her değişkenin bir veri tipi vardır.
Bütün programlama dillerindeki veri tiplerini sınıflayacak olursak 5 ana başlık altında toplayabiliriz.
1.Karakter Tabanlı Veri Tipleri: String ,char vs.
2.Sayı Tabanlı Veri Tipleri: int,float,double,vs.
3.Karar Tabanlı Veri Tipleri: bool vb.
4.Dizi ve Pointer Tabanlı Veri Tipleri
5.Kullanıcı Tabanlı Veri Tipleri:Kendi oluşturduğumuz nesnelerle oluşturduğumuz değişkenler.

  Bu sınıflamada karakter tabanlı veri tiplerinin  diğerlerinden farklı bir özelliği vardır.Bilindiği gibi bütün veri tipleri bu veri tiplerine dönüşebilir, yada bu  veri tiplerini diğer tiplere dönüştürebiliriz.Daha özeline inerek diyebiliriz ki string(karakter dizisi) bütün veri tiplerini içinde taşıyabilmektedir.Özellikle ekrana bir şey yazdıracağımızda yada ekrandan okuma yapacağımızda başvuracağımız veri tipi stringtir.Dolayısıyla biz  de bash kabuğunda (siyah ekranda ) çalıştığımız için aksi belirtilmedikçe (declare – i,typeset -i gibi)   -dizileri dışarda tutarak diyebiliriz ki -bütün değişkenlerin veri tipleri stringtir.

  Bash ‘ta değişkeni veri tipi belirtmeden doğrudan belirtiriz ki zaten yukarda anlattığımız gbi gerek de yoktur.Bir değişkenin değerini okurken $ işaretini kullanırız.

Ders2Ornek1.sh
 
#!/bin/bash
a=5
b=ahmet
c=”mehmet”
d=’ali’
echo $a $b $c $d
b=5
a=ahmet
c=3.4
echo $a $b $c

Örnekte de görüldüğü gibi aynı değişkene farklı değerleri atayabiliyoruz ama bu değerlerin  hepsinin veri tipi stringtir.Bunu anlamak için aşağıdaki örneği yapabiliriz.

Örnek:
Ders2Ornek2.sh
 
#!/bin/bash
a=5
b=5
echo  Toplam=$a+$b
Eğer bu değişkenler string değil de integer ise sonucun 9 olması lazım,ama sonuc “5+4”dür yani string bir ifadedir.Fakat bu değerler istendiği zaman çeşitli komutlar ya da anahtar kelimelerle istenen veri tiplerine dönüştürülebilir.

 typeset,declare,local
typeset ve declare aynıdır local ise sadece fonksiyonlar içinde kullanılabilir.Aldıkları parametreler şunlardır:

a Dizi tanımlama.
-f Fonksiyon adları için kullanılır.
-i İnteger değişken tanımlama.
-p Değişkenlerin  niteliklerini, tanımlanma şeklini,kriterlerini gösterme.
-r Değişkenin salt okunur (readonly) yani değerini sabit kılma.
-t Değişkenlere trace(iz) niteliği verme.
-x Her değişkeni diğer komutlar için işaretleme.

Örnek:
Ders2Ornek3.sh
 
#!/bin/bash
 declare -i a=25
echo $a #25 yazar
a=”string” # integer bir değişkene string bir değer atanıyor
echo  $a  # 0 yazar çünkü değişkenin veri tipi integer’dır
declare -p a # declare -i a="0" yazacaktır.Yani değişkenin açıklmasını yaparak,değişken integerdır ve değeri şudur demektedir.
local ile de aynı parametreleri  fonksiyon içinde kullanabiliriz.local tanımlaması,başka dillerden de hatırlayacağımız gibi değişkenin fonksiyon dışına çıkmamasını sağlar.Fakat declare ve typeset ile de  fonksiyon içinde  tanımladığımız  değişken dışarı çıkamaz.
 Örnek:
ders2Ornek4.sh
 

#!/bin/bash

function f1()
{
echo “Fonksiyon içindeyiz”
tiptanimsiz=2
typeset -i  a=25
declare -i b=35
local -i    c=45
echo $tiptanimsiz
echo $a
echo $b
echo $c
}


f1
echo “Dışardayız”
if [ -z $tiptanimsiz ]; then
echo  tiptanimsiz tanımlı değil
else
echo $tiptanimsiz
fi

if [ -z $a ]; then
echo  a tanımlı değil
else
echo $a
fi

if [ -z $b ]; then
echo  b tanımlı değil
else
echo $b
fi
if [ -z $c ]; then
echo  c tanımlı değil
else
echo $c
fi

let, expr,((  ... ))

Yukardaki ifadelerin hepsi aritmetik işlem yapmamızı sağlar.expr komutunun temel işlevi artitmetik işlemler  olmasa da böyle bir işlevi de vardır. (( ...)) ifadesi aritmetik işlemler yanında C tarzı ifadelerin kullanılmasını sağlar.Örneğin bu ifade sayesinde for((i=0;i<10;i++)) şeklinde for döngüsünü kullanabiliriz.Bu ifadeyi string içerikli bir değerle  kullanırken içeriği sayısal olarak değerlendireceği için  hata alınabilir, bu yüzden kullanırken dikkatli kullanmalıyız.Örneğin “if((“ali”==”veli”))”  ifadesi içeriklerini  sayısal olarak 0 olarak değerlendireceği için true sonuç döndürür ama “if((5==7)) “ ifadesi sağlıklı bir  şekilde false sonuc verir.Bu ( let, expr,((  ... ))  ) ifadeler aritmetik işlemler için aşağıdaki gibi kullanılır.

Örnek:
Ders2Ornek4sh
 
#!/bin/bash
a=9
b=8
c=7
d=6
e=5
f=4
let x=a*b
y=$( expr $c + $d )
z=$(( e - f))
echo a*b=$x
echo c+d=$y
echo e-f=$z

Ondalık Sayıların Kullanımı
Yukarda da belirttiğimiz gibi  a=10.55 ifadesi string bir ifadedir ama  bu ifadeyi başka bir komuta parametre olarak verip  ondalık bir sayı  olarak işlem yapıp sonucu tekrar string olarak alabiliriz.

Örneğin şu şekilde bir C programımız olsun:

//flt.c
 
int main(int argc,char* argv[])
{
 if( argv[1]==NULL)return 0;
  float f1 = atof(argv[1]);
  float f2= atof(argv[2]);
  printf("%0.2f\n",(f1*f2)); //bash için dönüş noktası
  return 0;
}
gcc -o flt flt.c  şeklinde programı derledikten sonra aşağıdaki kodu çalıştırabiliriz.Program parametreleri alıp floata dönüştürüp çarpıp bize sonucu geri döndürür.


Ders2Ornek5sh
 
#!/bin/bash
a=10.7
b=4.9
echo $(./flt1 $a $b) # $(komut) şeklinde bir komutun dönüşünü alabiliriz.

Tabi ki bu konuda bizim ilkel programımıza göre çok daha yetenekli bir hesap makinesi vardır bash da kullanılabilen.bc komutuyla ondalık(kesirli) sayılarla her türlü matematiksel işlemleri yapabiliriz.

Ders2Ornek6sh
 
#!/bin/bash
a=10.7
b=4.9
echo “$a* $b”|bc   #  “|” pipe işaretidir. Solundaki komutun çıktısını sağındaki komut satır satır okur.
c=$(echo “$a* $b”|bc )
echo $c

Değişken değeri içerisinde baştan ve sondan  silme 
${degisken#kelime} ${degisken##kelime} baştan siler
${degisken%kelime} ${degisken%%kelime} sondan siler

Yukardaki ifadelerden biri  ile (1 tane kısa ifadeler,2 tane uzun ifadeler için) değişkeninin içindeki değer içinde silme yapabiliriz.Ama biz sadece çıktıda silme yaparız değişkenin değeri değişmez.Değişkenin değerini değiştirmek için tekrar çıktıyı değişkene atamalıyız.

Ders2Ornek7sh
 
#!/bin/bash
a=armut
b=armut
echo ${a#ar} # mut yazar
echo $a  #armut yazar
a=${a#ar}
echo $a #mut yazar

echo ${b%mut} # ar yazar
echo $b #armut yazar
b=${b%mut}
echo $b #ar yazar


Değişken içinden istenen kısmı alma
${degisken:index:lenght}
Yukardaki ifade ile değişkenin indexin belirttiği harften itibaren lenght kadar kısmını almamızı sağlar.(index sıfırdan başlar)

Ders2Ornek8sh
 
#!/bin/bash
a=birikiüç
echo ${a:3:3} # iki yazar

İndirect expansion !
Değişken içindeki değeri bir değişken gibi kullanmamızı sağlar, ama unutmayın bu bir pointer değil sadece değişkenin içeriğini verir ve bir aşama daha ileri gitmez.Yani ${!a} çalışır ama ${!!a} yada ${!${a}} çalışmaz.Aynı işlemi eval komutuyla \$$ şeklinde kullanarak da yapabiliriz.


Ders2Ornek9sh
 
#!/bin/bash
a=5
b=a
echo ${!b} # 5 yazar
eval "echo \$$b" # yine 5 yazar



Yukardaki sınıflamamıza dönersek bahsetmediğimiz 3 sınıflama kaldı  dizileri(dizi tabanlı) gelecek ders göreceğiz, karar tabanlı olanları 0(false) 1(true) şeklinde ifade edebiliriz.Ama unutmayın linuxta sistem fonksiyonları başarı durumunda sıfır döndürür.Peki son maddeye gelirsek,kendi nesnelerimizi oluşturabilir miyiz?bash nesne yönelimli programlamayı (OOP) desteklemez.Ama biraz ilüzyonla bash’ı kandırabiliriz.

Örnek:
mystruct.sh
 
#!/bin/bash
function mystruct() #kurucu fonksiyon
{
this=$1

export ${this}_ad=$2  #nokta yerine yapı elemanına ulaşmak için _ (alt tireyi) kullanacağız.
export ${this}_soyad=$3  #fieldleri tanımlıyoruz
export ${this}_yas=$4


}

main.sh
 
]#!/bin/bash
  . mystruct.sh  #mystruct.sh dosyasını import ediyoruz
main(){

mystruct ilk ahmet kara 23 # nesnemizi oluşturuyoruz.
mystruct iki mehmet kara 24
echo $ilk_ad  $ilk_soyad $ilk_yas #çıktıyı alıyoruz.
echo $iki_ad  $iki_soyad $iki_yas

}
main

Çıktı şu şekilde olur.
ahmet kara 23
mehmet kara 24

Unutmayın yukardaki kod diğer programlama dillerindeki gibi  bir nesne oluşturmaz,sadece öyle algılamamızı sağlar yada  belki de diğer programlam dillerinde de nesne oluşmuyordur da biz öyle zannediyoruzdur.Smile

Konu ve anlatım çok güzel.
Teşekkürler
 DERS 2

Başlamadan birkaç önbilgi

1) “. “   ifadesi başka bir bash dosyasını import etmemizi sağlar

2) “export” ifadesi değişkenin çalıştığı kabuk ve alt kabuklarda tanınmasını sağlar,bir nevi değişkeni globalleştirir.Bash’te bir scripti çalıştırdığımızda yeni bir kabuk açılır program çalışır ve kabuk kapanır.Dolayısıyla  programı çalıştırdığımız kabuk, komutu başlattığımız kabuğun alt kabuğudur, ayrıntı için fork fonksiyonunu inceleyebilirsiniz.Ama unutmayın,export ifadesi  ana kabukta kullanılmış ise alt kabuklar değişkeni tanır; ama tersi durumda alt kabukta kullanıldığı bir değişkeni ana kabuk yada diğer kardeş alt kabuklar tanımaz.

3) ”eval” komutu verilen string bir ifadenin kabukta çalışmasını sağlar.Ör: eval “a=5 && echo $a” ekranda 5 yazar.Kabukta tekrar echo $a yazdığımızda değişkenimiz ordadır ve yine 5 yazar. 

Değişkenler

Bildiğimiz gibi değişkenler veri tutmaya yarar, dolayısıyla da her değişkenin bir veri tipi vardır.
Bütün programlama dillerindeki veri tiplerini sınıflayacak olursak 5 ana başlık altında toplayabiliriz.
1.Karakter Tabanlı Veri Tipleri: String ,char vs.
2.Sayı Tabanlı Veri Tipleri: int,float,double,vs.
3.Karar Tabanlı Veri Tipleri: bool vb.
4.Dizi ve Pointer Tabanlı Veri Tipleri
5.Kullanıcı Tabanlı Veri Tipleri:Kendi oluşturduğumuz nesnelerle oluşturduğumuz değişkenler.

  Bu sınıflamada karakter tabanlı veri tiplerinin  diğerlerinden farklı bir özelliği vardır.Bilindiği gibi bütün veri tipleri bu veri tiplerine dönüşebilir, yada bu  veri tiplerini diğer tiplere dönüştürebiliriz.Daha özeline inerek diyebiliriz ki string(karakter dizisi) bütün veri tiplerini içinde taşıyabilmektedir.Özellikle ekrana bir şey yazdıracağımızda yada ekrandan okuma yapacağımızda başvuracağımız veri tipi stringtir.Dolayısıyla biz  de bash kabuğunda (siyah ekranda ) çalıştığımız için aksi belirtilmedikçe (declare – i,typeset -i gibi)   -dizileri dışarda tutarak diyebiliriz ki -bütün değişkenlerin veri tipleri stringtir.

  Bash ‘ta değişkeni veri tipi belirtmeden doğrudan belirtiriz ki zaten yukarda anlattığımız gbi gerek de yoktur.Bir değişkenin değerini okurken $ işaretini kullanırız.

Ders2Ornek1.sh
 
#!/bin/bash
a=5
b=ahmet
c=”mehmet”
d=’ali’
echo $a $b $c $d
b=5
a=ahmet
c=3.4
echo $a $b $c

Örnekte de görüldüğü gibi aynı değişkene farklı değerleri atayabiliyoruz ama bu değerlerin  hepsinin veri tipi stringtir.Bunu anlamak için aşağıdaki örneği yapabiliriz.

Örnek:
Ders2Ornek2.sh
 
#!/bin/bash
a=5
b=5
echo  Toplam=$a+$b
Eğer bu değişkenler string değil de integer ise sonucun 9 olması lazım,ama sonuc “5+4”dür yani string bir ifadedir.Fakat bu değerler istendiği zaman çeşitli komutlar ya da anahtar kelimelerle istenen veri tiplerine dönüştürülebilir.

 typeset,declare,local
typeset ve declare aynıdır local ise sadece fonksiyonlar içinde kullanılabilir.Aldıkları parametreler şunlardır:

a Dizi tanımlama.
-f Fonksiyon adları için kullanılır.
-i İnteger değişken tanımlama.
-p Değişkenlerin  niteliklerini, tanımlanma şeklini,kriterlerini gösterme.
-r Değişkenin salt okunur (readonly) yani değerini sabit kılma.
-t Değişkenlere trace(iz) niteliği verme.
-x Her değişkeni diğer komutlar için işaretleme.

Örnek:
Ders2Ornek3.sh
 
#!/bin/bash
 declare -i a=25
echo $a #25 yazar
a=”string” # integer bir değişkene string bir değer atanıyor
echo  $a  # 0 yazar çünkü değişkenin veri tipi integer’dır
declare -p a # declare -i a="0" yazacaktır.Yani değişkenin açıklmasını yaparak,değişken integerdır ve değeri şudur demektedir.
local ile de aynı parametreleri  fonksiyon içinde kullanabiliriz.local tanımlaması,başka dillerden de hatırlayacağımız gibi değişkenin fonksiyon dışına çıkmamasını sağlar.Fakat declare ve typeset ile de  fonksiyon içinde  tanımladığımız  değişken dışarı çıkamaz.
 Örnek:
ders2Ornek4.sh
 

#!/bin/bash

function f1()
{
echo “Fonksiyon içindeyiz”
tiptanimsiz=2
typeset -i  a=25
declare -i b=35
local -i    c=45
echo $tiptanimsiz
echo $a
echo $b
echo $c
}


f1
echo “Dışardayız”
if [ -z $tiptanimsiz ]; then
echo  tiptanimsiz tanımlı değil
else
echo $tiptanimsiz
fi

if [ -z $a ]; then
echo  a tanımlı değil
else
echo $a
fi

if [ -z $b ]; then
echo  b tanımlı değil
else
echo $b
fi
if [ -z $c ]; then
echo  c tanımlı değil
else
echo $c
fi

let, expr,((  ... ))

Yukardaki ifadelerin hepsi aritmetik işlem yapmamızı sağlar.expr komutunun temel işlevi artitmetik işlemler  olmasa da böyle bir işlevi de vardır. (( ...)) ifadesi aritmetik işlemler yanında C tarzı ifadelerin kullanılmasını sağlar.Örneğin bu ifade sayesinde for((i=0;i<10;i++)) şeklinde for döngüsünü kullanabiliriz.Bu ifadeyi string içerikli bir değerle  kullanırken içeriği sayısal olarak değerlendireceği için  hata alınabilir, bu yüzden kullanırken dikkatli kullanmalıyız.Örneğin “if((“ali”==”veli”))”  ifadesi içeriklerini  sayısal olarak 0 olarak değerlendireceği için true sonuç döndürür ama “if((5==7)) “ ifadesi sağlıklı bir  şekilde false sonuc verir.Bu ( let, expr,((  ... ))  ) ifadeler aritmetik işlemler için aşağıdaki gibi kullanılır.

Örnek:
Ders2Ornek4sh
 
#!/bin/bash
a=9
b=8
c=7
d=6
e=5
f=4
let x=a*b
y=$( expr $c + $d )
z=$(( e - f))
echo a*b=$x
echo c+d=$y
echo e-f=$z

Ondalık Sayıların Kullanımı
Yukarda da belirttiğimiz gibi  a=10.55 ifadesi string bir ifadedir ama  bu ifadeyi başka bir komuta parametre olarak verip  ondalık bir sayı  olarak işlem yapıp sonucu tekrar string olarak alabiliriz.

Örneğin şu şekilde bir C programımız olsun:

//flt.c
 
int main(int argc,char* argv[])
{
 if( argv[1]==NULL)return 0;
  float f1 = atof(argv[1]);
  float f2= atof(argv[2]);
  printf("%0.2f\n",(f1*f2)); //bash için dönüş noktası
  return 0;
}
gcc -o flt flt.c  şeklinde programı derledikten sonra aşağıdaki kodu çalıştırabiliriz.Program parametreleri alıp floata dönüştürüp çarpıp bize sonucu geri döndürür.


Ders2Ornek5sh
 
#!/bin/bash
a=10.7
b=4.9
echo $(./flt1 $a $b) # $(komut) şeklinde bir komutun dönüşünü alabiliriz.

Tabi ki bu konuda bizim ilkel programımıza göre çok daha yetenekli bir hesap makinesi vardır bash da kullanılabilen.bc komutuyla ondalık(kesirli) sayılarla her türlü matematiksel işlemleri yapabiliriz.

Ders2Ornek6sh
 
#!/bin/bash
a=10.7
b=4.9
echo “$a* $b”|bc   #  “|” pipe işaretidir. Solundaki komutun çıktısını sağındaki komut satır satır okur.
c=$(echo “$a* $b”|bc )
echo $c

Değişken değeri içerisinde baştan ve sondan  silme 

${degisken#kelime} ${degisken##kelime} baştan siler
${degisken%kelime} ${degisken%%kelime} sondan siler

Yukardaki ifadelerden biri  ile (1 tane kısa ifadeler,2 tane uzun ifadeler için) değişkeninin içindeki değer içinde silme yapabiliriz.Ama biz sadece çıktıda silme yaparız değişkenin değeri değişmez.Değişkenin değerini değiştirmek için tekrar çıktıyı değişkene atamalıyız.

Ders2Ornek7sh
 
#!/bin/bash
a=armut
b=armut
echo ${a#ar} # mut yazar
echo $a  #armut yazar
a=${a#ar}
echo $a #mut yazar

echo ${b%mut} # ar yazar
echo $b #armut yazar
b=${b%mut}
echo $b #ar yazar


Değişken içinden istenen kısmı alma
${degisken:index:lenght}
Yukardaki ifade ile değişkenin indexin belirttiği harften itibaren lenght kadar kısmını almamızı sağlar.(index sıfırdan başlar)

Ders2Ornek8sh
 
#!/bin/bash
a=birikiüç
echo ${a:3:3} # iki yazar

İndirect expansion !
Değişken içindeki değeri bir değişken gibi kullanmamızı sağlar, ama unutmayın bu bir pointer değil sadece değişkenin içeriğini verir ve bir aşama daha ileri gitmez.Yani ${!a} çalışır ama ${!!a} yada ${!${a}} çalışmaz.Aynı işlemi eval komutuyla \$$ şeklinde kullanarak da yapabiliriz.


Ders2Ornek9sh
 
#!/bin/bash
a=5
b=a
echo ${!b} # 5 yazar
eval "echo \$$b" # yine 5 yazar



Yukardaki sınıflamamıza dönersek bahsetmediğimiz 3 sınıflama kaldı  dizileri(dizi tabanlı) gelecek ders göreceğiz, karar tabanlı olanları 0(false) 1(true) şeklinde ifade edebiliriz.Ama unutmayın linuxta sistem fonksiyonları başarı durumunda sıfır döndürür.Peki son maddeye gelirsek,kendi nesnelerimizi oluşturabilir miyiz?bash nesne yönelimli programlamayı (OOP) desteklemez.Ama biraz ilüzyonla bash’ı kandırabiliriz.

Örnek:
mystruct.sh
 
#!/bin/bash
function mystruct() #kurucu fonksiyon
{
this=$1

export ${this}_ad=$2  #nokta yerine yapı elemanına ulaşmak için _ (alt tireyi) kullanacağız.
export ${this}_soyad=$3  #fieldleri tanımlıyoruz
export ${this}_yas=$4


}

main.sh
 
]#!/bin/bash
  . mystruct.sh  #mystruct.sh dosyasını import ediyoruz
main(){

mystruct ilk ahmet kara 23 # nesnemizi oluşturuyoruz.
mystruct iki mehmet kara 24
echo $ilk_ad  $ilk_soyad $ilk_yas #çıktıyı alıyoruz.
echo $iki_ad  $iki_soyad $iki_yas

}
main

Çıktı şu şekilde olur.
ahmet kara 23
mehmet kara 24

Unutmayın yukardaki kod diğer programlama dillerindeki gibi  bir nesne oluşturmaz,sadece öyle algılamamızı sağlar yada  belki de diğer programlam dillerinde de nesne oluşmuyordur da biz öyle zannediyoruzdur.Smile

(Konu bütünlüğü açısından Ders 2, 1.yorumun devamına da eklendi.)