Scripting 101
Bu eğitim ile Linux sistemlerinde çalışan, işlerimizi otomatize eden scriptlerin nasıl yazıldığı ve temel algoritma oluşturma hakkında bilgi alacaksınız.
Bash Scripting Yapısı ve Bash’e Giriş
Shell ve Bash Nedir? Scriptler Ne İşe Yarar?
Bash eğitim serimizde, Linux 101 eğitiminden sonra aşina olduğumuz CLI (command line interface) üzerinde yapmak istediğimiz işlemleri uzun uzun komut satırları ile uğraşmak yerine yazdığımız bir script(senaryo) dosyayı ile otomatize etmek amacıyla kullanacağımız Bash’e giriş yapacağız.
Öncelikle Bash ne ona bir göz atalım.
Kısaca shell(kabuk) Linux çekirdeğini çevreler. Bu kabuğun ise pek çok çeşidi vardır; tcsh, zsh, csh ve bash
. Kullandığınız shell türüne göre shell ile iletişime geçme tarzınız değişir. CLI üzerinden echo $SHELL
komutunu çalıştırdığımızda çekirdeğimiz bize kullanılan shell değişkenini söyleyecektir, farklı shell türleri olduğu için bu da bir değişkendir.
Peki bu otomatize işler kimlerin işine yarayacak? Herkesin işine yarayabilir, eğer ki bir sistem yöneticisi iseniz yazdığınız bir script ile her pazartesi sabahı değiştirdiğiniz veya güncellediğiniz bir dosyayı yazdığınız Bash scriptine yaptırabilirsiniz. Açık Kaynak Fikirler üzerinden Linux 101 eğitimini bitirmiş bir kişi yazdığı bir Bash scripti ile dosyalarını kontrol edebilir, dosya izinlerini kontrol edebilir, paketlerini sürekli güncel tutabilir, işlemlerini (processlerini) yönetebilir, serverların kontrolünü sağlayabilir.
Buna örnek vermek gerekirse;
Bash ile dosya kontrolü ve izin denetimi: Scriptiniz her gün dosyalarınızın silinip silinmediğini, planlandığı dizinde mi durduğunu, dosya erişim izinlerinin güncel veya değiştirilmişse bile istediğiniz şekilde tekrar düzenlemenizi sağlayabilirsiniz.
Bash yazma ortamları: nano, vi, vim, Atom veya Microsoft Visual Studio Code üzerinden scriptlerimizi yazabiliriz, eğer Linux bilgisayarınızı sanal makine üzerinden kullanıyorsanız ve Microsoft Visual Studio Code kurmak istemiyorsanız ana bilgisayarınız üzerinden yazdıktan sonra kopyala-yapıştır ile sanal makinenize aktarabilirsiniz.
Örneklere Erişim ve Docker
Scripting 101 eğitimimiz boyunca pek çok örnek üzerinden konu başlıklarımızı işleyeceğiz. Eğitim için hazırlanan 50’den fazla örneğe ulaşmak için ise Docker teknolojisini kullanacağız. Açık Kaynak Fikirler platformu üzerinden sunulan eğitimler, kullanıcıların kolay şekilde pratik yapması için kullanıcılara konteyner sunucular sağlamaktadır, bunun için de Docker teknolojisi kullanılmaktadır. (Docker 101 eğitimine buradan ulaşabilirsiniz.)
Kısaca Docker bilgisayar içerisinde ufak sanal makineler oluşturmaya yarıyor ve bizde Docker üzerinden oluşturulmuş bir sanal makineye tekrar bir sanal makine kurarak eğitimimize örnekler ile beraber devam edeceğiz. Yalnızca 1-2 komut girerek bu işlemi sağlayacağız.
docker run -dit --name scripting101 erdates/scripting101 ; docker exec -it scripting101 bash
Komutlarını çalıştırdıktan sonra scripting101
isimli 75 megabytelık ufak bir Ubuntu imajı indirilecek ve eğitimler için kullanacağımız konteyner çalışacaktır.
Unable to find image 'erdates/scripting101:latest' locally
latest: Pulling from erdates/scripting101
da7391352a9b: Pull complete
14428a6d4bcd: Pull complete
2c2d948710f2: Pull complete
964f74000710: Extracting [==================================================>] 7.949kB/7.949kB
Alacağımız bu çıktı 75 megabytelık Ubuntu Docker imajının indirilme anını gösteriyor. Kurulum tamamlandıktan sonra yukarıda girdiğimiz exec
komutu ile konteyner içine direkt root
halinde dahil olacağız. Bu çıktı şu şekilde olacaktır.
root@44656d7998fa:/#
#Artık konteyner içinde root olarak yetkiliyiz.
Şimdi ise yeni oluşturuduğumuz sanal makine içinde ls
komutunu gönderirsek
bin dev home lib32 libx32 mnt ornekler* root sbin sys usr
boot etc lib lib64 media opt proc run srv tmp var
şeklinde sahip olduğumuz dizinler karşımıza çıkacaktır. cd /ornekler/
dersek örneklerin bulunduğu dizine erişmiş olacağız. ornekler
dizinine eriştikten sonra ls
diyerek bütün örneklere erişim sağlayabilirsiniz.
Ufak bir Ubuntu sistemi kullandığımız için bazı komutlar eksik olabilir, eksik olan komutlar için öncelikle apt update
ardından apt install komut
şeklinde komutu yükleyebilirsiniz.
Dilerseniz script ortamına bir bakalım, bulunduğumuz klasörde nasa.sh
adlı dosyaya göz atalım. Peki bu .sh
uzantısı ne? Bu uzantı Bash’in son 2 harfinden gelmekte ve bize bunun bir Bash script olduğunu belirtiyor. cat nasa.sh
dediğimizde karşımıza NASA sistemine girmemizi sağlayan eğlenceli bir script çıkacak.
cat nasa.sh
#!/bin/bash
echo "NASA sistemine giriliyor"
sleep 1
echo "..."
sleep 1
echo "NASA sistemine girildi"
sleep 1
echo "..."
sleep 1
echo "NASA'ya hoşgeldiniz
İlk satırda karşımıza çıkan #!/bin/bash satırı bize bu scriptin çalışması için gerekli komutları sağlıyor, hatırladığınız üzere bin klasörü Linux komutlarının bulundurulduğu bir klasör. Ardından ise belirttiğimiz şekilde komutlar çalıştırılmaya başlanıyor.
Scriptler nasıl çalıştırılır? ls
komutunu çalıştırdığımızda pek çok .sh uzantılı dosya göreceğiz, bu dosyalar yeşil renk ile farklı gösterilmekteler. İsimlerinin yeşil olması bu dosyaların çalıştırılabilir olduğu anlamına gelmektedir. Eğer yazdığınız bir script yeşil renk ile yazılmamışsa çalıştır komutu gönderdiğiniz zaman scriptiniz görevini yapmayacaktır. Linux 101 eğitiminde 2.ünite 9. bölümde belirttiğimiz chmod
komutu ile dosyamızı çalışır hale getirebiliriz.
chmod +x script_ismi.sh
komutunu kullanacağız
Dosyamızı kullanıma hazır hale getirdik, peki nasıl çalıştıracağız? Kullandığımız shell ismini belirtip ardından dosyamızın adını yazarsak dosyamız çalışacaktır, bash script_ismi.sh
veya ./script_ismi
şeklinde de kullanabiliriz. Kurs boyunca ben ./ ile dosyalarımızı çalıştıracağım, isterseniz sizler bash script_ismi.sh
şeklinde çalıştırabilirsiniz.
Dilerseniz biraz önce bahsettiğimiz nasa.sh
dosyamızı çalıştırarak bize nasıl bir output(çıktı) verecek ona bakalım.
cat nasa.sh
ile scriptimize baktığımızda echo
ve sleep
komutları sırası ile çalışarak bizlere outputlar verdi.
İsterseniz bir örnek daha olması için adduser.sh
scripti ile kullanıcı oluşturma ve şifre atama işlemlerini yazdığımız script dosyasına yaptıralım. Scripti çalıştırma komutundan sonra istediğimiz kullanıcı ismini belirtmemiz gerekiyor.
./adduser.sh kullanıcı_adı
şeklinde çalıştırıp, kullanıcı_adı
kısmına istediğiniz kullanıcı adını yazınız. Şu an işlemleri yaptığınız kullanıcı eğer root değilse ve bu işlem sırasında izin hatası alıyorsanız sudo
komutu ile çalıştırmayı unutmayın. cat adduser.sh
ile dosyayı incelediğimizde sırasıyla echo, sleep, useradd
ve passwd
komutlarının olduğunu göreceğiz. Bunları tek tek yazmak yerine scriptimiz içinde bir sıra ile yazarak otomatize etmiş oluyoruz. tail -1 /etc/passwd
komutu ile oluşturduğunuz kullanıcıyı kontrol edebilirsiniz.
Kabuk Karakterleri ( ? * [ ] ; ^ ~ )
Bu karakterler CLI üzerinden kabuk ile etkileşime geçtiğimiz zamanda bize fonksiyonlar sağlayan araçlardır.
? Karakteri :
Bir sorgu sağladığımızda bize harflendirme sınırlandırması sağlar. Örnek olarak ls /bin/a??
sorgusunu gönderdiğimizde bize /bin/apt & /bin/awk
çıktısını verecektir, böylece /bin altında bulunan a ile başlayan 3 karakterli içerikler gelecektir.
* Karakteri :
Bu karakter “her” anlamına gelmektedir. ls /bin/a*
sorgusunu gönderdiğimizde bize /bin altında bulunun a ile başlayan her içeriği gösterecektir. Fakat ls
/bin/*a
sorgusu gönderirsek /bin altında bulunun, a ile biten içerikleri gösterecektir.
[ ] Karakteri :
Yaptığımız sorgular sırasında bizlere seçenekler sunan karakterin kullanımı şu şekildedir: ls /bin/[a-c]*
sorgusu bize a,b,c ile başlayan bütün eşleşmeleri getirecektir.
; Karakteri :
Noktalı virgül işareti ise bize birden fazla sorgu yapmamızı sağlar, pipe ( | ) işareti ile karıştırmamalıyız. Pipe işareti bize komutların aralarında etkileşime girmemizi sağlamaktadır. uname;date;whoami
komutlarını bu şekilde girdiğimizde bize işletim sistemi, tarih, kullanıcı bilgilerini döndürecektir. uname|date|whoami
sorgusu ise bize sadece işletim sistemi bilgisini verecektir, çünkü komutlar birbirleriyle etkileşime girmeyeceği için sadece bir komut çalışacaktır.
^ Karakteri :
Bu karakter olumsuzluk sorgusu içeren işlemler sırasında kullanılır.
ls -a [^a]*
komutu, içinde bulunduğumuz klasörde a ile başlamayan bütün içerikleri bize sunar.
~ Karakteri :
Tilde isminde olan bu karakter Linux içinde kullanıcıya ait /home dizinine eş değerdir.
cd ~
sorgusu bizi direkt olarak /home/kullanıcı_adı dizinine götürecektir.
Diğer karakterlere buradan ulaşabilirsiniz.
Değişkenler (env, export)
Linux ortamında 2 tip değişken olmak üzere sistem ve kullanıcı tanımlı değişkenler vardır.
Sistem değişkenlerini CLI üzerinde env komutu ile görebiliriz. Hatta env | wc
yazarsak 9’a yakın sistem değişkenimiz olduğunu görürüz. İlk sistem değişkeni(HOSTNAME) kullandığımız sunucu adını belirtilmekte, PWD değişkeni bulunduğumuz klasörü gösterir. echo $PWD
komutu PWD’nin sahip olduğu değeri bize çıktı olarak verir. $ işareti ile belirttiğimiz kelimeler, değişken anlamı kazanır.
Sistem değişkenleri nasıl değiştirilir veya yeni değişken nasıl eklenir?
Linux sistemimize bir sistem değişkeni eklemek istediğimiz zaman öncelikle CLI üzerinden değişken ve tanımı belirttikten sonra export
komutu ile sistem değişkenlerine yollayacağız.
Örnek olarak diyelim ki yönettiğiniz sistemde sürekli IP adresleri üzerinden işlem yaptığınız 2 adet bilgisayar var, sürekli bu IP adreslerini tek tek yazmak yerine sistem değişkenleri olarak atayıp, işlemlerinizi değişkenler üzerinden yapabilirsiniz. Örnek ile bir göz atalım şimdi.
Sisteminizdeki IP adresleri şu şekilde:
birinci_bilgisayar_ip = 192.23.203.45
ikinci_bilgisayar_ip = 192.24.204.48
CLI üzerinden önce değişkenleri ve değerleri aralarında boşluk olmadan giriyoruz.
birinci_bilgisayar_ip=192.23.203.45
ikinci_bilgisayar_ip=192.24.204.48
Girdiğimiz bu değişkenleri sistem değişkenlerine atamadığımız sürece bu değişkenler sistem değişkeni olarak geçmeyecektir. Bilgisayarınızı açıp kapattığınız zaman gideceklerdir.
Değişkenleri görmek için
env | grep “birinci_bilgisayar_ip”
ve env | grep “ikinci_bilgisayar_ip”
komutlarını gönderdiğimiz zaman CLI üzerinden bir sonuç gözükmeyecektir. Fakat
sırasıyla export birinci_bilgisayar_ip
ve export ikinci_bilgisayar_ip
komutlarını girersek değişkenlerimiz tanımlanacaktır.
Şimdi env | grep “birinci_bilgisayar_ip
ya da env | grep “ikinci_bilgisayar_ip
komutlarını gönderdiğimiz zaman sistem değişkenlerinin tanımlanmış bir şekilde ekranımıza bastırılacaktır. Değişkenleri sistemden silmek için unset
komutunu kullanabiliriz.
unset birinci_bilgisayar_ip
komutunu girersek, değişkenimiz silinecektir.
Kullanıcı değişkenleri
bizim tanımladığımız değişkenlerdir örnek olarak /ornekler dizininde bulunan toplama.sh
scriptine göz atalım.
cd /ornekler
cat toplama.sh
birinci_deger=10 #Değişkenler ile değerlerin arasında boşluk olmamasına dikkat edelim.
ikinci_deger=20
echo $birinci_deger
echo $ikinci_deger
echo $(( birinci_deger+ikinci_deger )) #Parantezler ve değişkenler arasında 2 birim boşluk bırakıyoruz.
toplam=birinci_deger+ikinci_deger
echo $(( toplam )) #Toplam değişkenini ekrana bastırırken 2 birim boşluğu unutmuyoruz
Bu değişkenleri çağırmamız için $(değişken sembolü) ve parantezler ile çağırmamız lazım.
Bu iki değerin toplamını yazabilmek için echo komutu ile değişkenleri çağırıyoruz.
Ve bu iki değerin toplamını da toplam değişkenine atıyoruz.
./toplama.sh
dediğimiz zaman bize 10, 20, 30, 30 değerlerini döndürecektir.
Terminali Özelleştirmek - ezprompt.net kullanımı
Kullandığımız terminalde değişiklik yapabiliriz, laboratuvar ortamımızda terminal bizlere root@IP adresi ~/Bulunduğumuz Dizin
şeklinde default olarak verilmiştir ve yazı rengi olarak beyaz sunulmuştur. Bu kullanım şeklini sizler isterseniz kullanıcı bilgisini terminal üzerinden kaldırabilir hatta IP bilgisini de kaldırabilirsiniz, sadece bulunduğumuz dizinin gözükmesini sağlayabilirsiniz. Ayrıca terminalimizde gözüken bu bilgileri farklı renklere göre de tanımlayabilirsiniz.
Terminali kullanış şeklimizin nasıl olduğunu, Linux kernelimizde bu bilgileri içinde barından bir değişken vardır. echo $PS1
komutunu yazarsak karşımıza bilgilerimiz çıkacaktır. ezpormt isimli websitesi üzerinden terminalinizin görüntüsünü dilediğiniz gibi değiştirebilirsiniz. Örneğin kullanıcı ismi beyaz, IP bilgisi gözükmesin, bulunduğumuz dizin yeşil renkte olsun şeklinde düzenleyebiliriz. Hatta kullanıcı ismi ile dizin bilgisinin arasında “:” olsun. ezpormt üzerinden isteklerimize göre ayarlarımızı yaptıktan sonra bize
export PS1="\u:\[\e[32;40m\]\W\[\e[m\]"
şeklinde bir komut dizini vericektir. Bu PS1
değişkenini ezprompt.net üzerinde konfigüre ettiğimiz şekilde değiştirecektir. Komutu çalıştırdığımızda (export PS1=…) terminalimizin özelleştiğini görebiliriz.
Argümanlar
Argümanlar başlığı bash scripting alanında önemli bir yere sahiptir çünkü sorgularımızı argümanları kullanarak yapıyoruz. Labaratuvar içinde bulunan arg.sh
adlı programımızın içeriği aşağıdaki gibidir:
echo $0 $1 $2
Bu scriptimizin amacı bizim tarafımızdan verilen 0, 1, ve 2 numaralı değişkenleri ekrana yazdırmaktır. Scriptimizi çalıştırmak için ./arg.sh
yazdıktan sonra scriptin içine gönderilecek 1 ve 2 numaralı değişkenleri veriyoruz:
./arg.sh açık kaynak fikirler
Bu şekilde “açık”, “kaynak”, “fikirler” değişkenlerini CLI(komut satırı) üzerinden scripte gönderiyoruz, peki içinde echo komutu ve $0 $1 $2
değişkenleri bulunan scriptleri yukarıda ki gibi çalıştırırsak ekranımıza nasıl bir çıktı gelecek?
Çıktı ./arg.sh açık kaynak
şeklinde oluştu, peki “fikirler” girdisine ne oldu? Fark ettiyseniz yukarıda “1 ve 2 numaralı değişkenleri gönderiyoruz” dedik, çünkü script içinde sadece $0 $1 $2 değişkenlerine yer verdik, bu da demek oluyor ki bu script sadece 2 adet değişken alabilir. Nedeni ise $0 değişkeni programımızın çalıştırılma komutunu olmasıdır. Fikirler argümanına programın içinde yer bulabilmesi için bir yer göstermedik bu yüzden de çıktı olarak ekrana gelmedi.
echo $0 $1 $2 $3 şeklinde programımızı düzenlersek ./arg.sh açık kaynak fikirler
şeklinde çalıştırırsak komutumuz girilen bütün argümanları ekrana bastıracaktır. Şimdi gelin diğer argüman çeşitlerine bakalım.
@ Argümanı : Programın kendi adı hariç girilen bütün argümanları kabul eder ve $1, $2, $3 ...
argümanlarına otomatik atar. arg_@.sh
programına göz atarsak, şu şekildedir.
echo $@
echo $1
echo $2
echo $3
Bu scripti ./arg_@.sh açık kaynak fikirler
şeklinde çalıştırırsak çıktımız aşağıdaki gibi olacaktır.
açık kaynak fikirler
açık
kaynak
fikirler
# Argümanı : Programın kaç adet argüman aldığını bize söyler. arg_#.sh
scriptine bir göz atalım.
cat arg_#.sh
echo $@
echo $#
./arg_# açık kaynak fikirler
şeklinde çalıştırırsak.
açık kaynak fikirler
3
Çıktısını alırız.
Örnek olması açısından bir program dilleri listesi üzerinden gidebiliriz, yazacağımız scripte 1’den fazla değer yollayacağız ve bu inputları bir değişkenler listesi içerisine atıp birinci indeksini ekrana yazdıracağız.
diller.sh isimli script içerisine bakalım.
cat diller.sh
diller=(”$@”) #Girilen bütün inputlar bu değişkene gönderildi.
echo ${diller[0]} ${diller[2]}
./diller.sh c python java
şeklinde argümanlar tanımlayalım. Çıktımız ilk ve son indeks olan c ve java argümanları olacaktır. Eğer bu örneğin sonuna echo $*
eklersek bütün değişkenleri bastıran bir satır elde ederiz.
Bash Ortamında Input Alma
toplama.sh
isimli örnekte değerlerimizi script içinde tanımlamıştık fakat çoğu zaman yazdığımız script ile etkileşime geçebilmemiz için input yolu ile yani kullanıcıdan alınan değerler ile işlemler yapmamız gerekecektir. read
komutu ile bu işlemi sağlayacağız, hatta deneme amaçlı olarak CLI üzerinde direkt read
yazarsak Linux bizden bir değer girmemizi bekleyecektir, değeri girip enter tuşuna bastığımız zamanda CLI üzerinde bir değişiklik olmayacaktır ve girilen değer kaybolacaktır. Fakat read
komutunu script içine dahil ettiğimizde CLI üzerinden girdiğimiz komutu scriptin içine aktaracaktır ve bu şekilde işlem yapabilecektir.
toplama.sh
dosyamızın ilk 4 satırı soldaki gibiydi, read komutunu eklediğimiz de ise sağdaki gibi gözükecektir ve outputu(çıktısı) daha anlaşılır bir halde olacaktır:
birinci_deger=10 read birinci_deger
ikinci_deger=20 read ikinci_deger
echo $birinci_deger echo “Birinci değer değişkeni = ” $birinci_deger
echo $ikinci_deger echo “İkinci değer değişkeni = ” $ikinci_deger
toplama.sh toplama_read.sh
Bu bilgiler ışığında toplama_read.sh
scriptinin yapısını inceleyelim.
Dosyamızı ./toplama_read.sh
şeklinde çalıştırdıktan sonra read birinci_deger
kısmı bize birinci_deger değişkenini sordu ve bizde istediğimiz değeri yazdık, read ikinci_deger
kısmı içinde aynısı geçerli. Ardından echo
komutu ile ekrana bastırılacak değerin hangisi olduğunu belirtip $birinci_deger
tanımlaması ile değişkeni belirttik, sonra ikinci değeri de echo
ile bastırdık.
Bu scriptimizi test ettikten sonra göreceğimiz gibi sonuç çok kullanışlı olmadı, bu durumu düzeltmek için yapacağımız işlem read
komutunun -p (promt)
parametresini kullanmak olacaktır. Değişkenlerin kontrolünü sağlamak için sonlarına echo komutlarını ekleyebiliriz. Buradaki örneği toplama_read2.sh
adlı script dosyasında tekrar inceleyelim.
cat toplama_read2.sh
read -p “Birinci değer değişkeni = ” birinci_deger
read -p “İkinci değer değişkeni = ” ikinci_deger
echo ${birinci_deger}
echo ${ikinci_deger}
Şeklinde düzenlersek scriptimizin daha kullanışlı olduğunu görebiliriz. Değişken alırken $ kullanılmadığına, değişken çıktı olarak gönderildiğinde ise $ ve {} kullanıldığına dikkat etmelisiniz.
read komutunun -a(array-dizi) parametresi ile kullanırsak birden fazla değer girebiliriz, -s(secret) parametresi ise girilen değerin ekranda gözükmesini engeller. read_a.sh
ve read_s.sh
örnekleri ile parametrelere bir göz atalım.
cat read_a.sh
echo "Birinci küme değerleri = "
read -a birinci_kume
echo "İkinci küme değerleri = "
read -a ikinci_kume
echo ${birinci_kume[0]},${birinci_kume[1]}
echo ${ikinci_kume[0]},${ikinci_kume[1]}
-a parametresi ile her küme için 2 adet değer alıyoruz ve girilen değerlerin indexlerini echo ile ekrana yazdırıyoruz.
Indexleme; Tanımlanan veri setlerinde değerlerin yerlerini göstermektir. Örnek olarak bir alışveriş listesinde alınacak ilk ürün elma ikincisi ise armut ise bu listenin ilk indexi elma olur. Indexleme işlemlerinde değerler 0’dan başlar, ilk değer 0. indexe denk gelmektedir.
cat read_sp.sh
read -p "Kullanıcı ismi : " kullanici_ismi
read -sp "Şifre : " sifre #s parametresi p ile beraber kullanılmalıdır.
-s parametresi girilen değişkenin ekranda görünmemesini sağlıyor, bu şekilde gizlilik gerektiren değişkenleri girebiliriz. -s parametresinin, -p(promt) parametresi ile beraber kullanılması gerekmektedir.
Koşul İfadeleri
Koşul ifadeleri yazılan scriptin kullandığı ve kullanacağı değişkenlerini, sistem değişkenlerini, dizin & dosya & klasör gibi birimlerinin durumlarını-değerlerini kontrol ederek script içinde bulunan algoritmanın nasıl ilerleyeceğini belirten ifadelerdir.
Sorguları sağlayan koşul ifadeleri if, elif, else dir.
if
= Koşul durumların ilk adımıdır, en başta olur ve bir kez kullanılır. fi ile bitirmeniz gerekir.
elif
= Koşul durumlarının 2. 3. 4. … durumlarını karşılaştırır.
else
= Hiçbir koşulu sağlamayan durumlarda kullanılır.
if ifadesinin çalışma mantığını if.sh
scripti içinde işlenmiştir. Script örneği içine bir komut yazacağız ve eğer böyle bir komut var ise echo komutu bize “Böyle bir komut var!” şeklinde bilgi verecek, eğer yoksa “Böyle bir komut yok!” şeklinde çıktı verecektir.
cat if.sh
if date #date komutunu kontrol ediyor
then #if şartı sağlanıyorsa çalışacak komutları ifade ediyor.
echo "Böyle bir komut var!"
else #if şartının sağlanmadığı durumları belirtir.
echo "Böyle bir komut yok!"
fi
Şimdi daha farklı bir komut deneyelim, dışarıdan bir değer alıp bu değerin bir komut olup olmadığını kontrol edelim, sonucu da tekrar echo ile ekrana verelim.
cat if2.sh
if $1 #Atanan komutunu kontrol ediyor
then #if şartı sağlanıyorsa çalışacak komutları ifade ediyor.
echo "Böyle bir komut var!"
else #if şartının sağlanmadığı durumları belirtir.
echo "Böyle bir komut yok!"
fi
./if2.sh pwd
dediğimizde bize “Böyle bir komut var!” cevabını dönecektir, ./if2.sh pvd
dediğimizde ise “Böyle bir komut yok!” cevabını verecektir.
Başka bir örnek ile elif kullanımını görelim. Diyelim ki CLI üzerinden scripte bir değer yolluyoruz ve bu değer 1’e eşitse kırmızı, 2’ye eşitse beyaz, 3’e eşitse siyah yazdırsın. Girilen değer 1, 2, 3 sayılarından birine eşit değilse de sarı yazdırsın. Bu durumu yukarıda bahsettiğimiz koşul ifadeleri ile eşleştirirsek.
if $1 = 1 > kırmızı
elif $1 = 2 > beyaz
elif $1 = 3 > siyah
else > sarı
Şeklinde olacaktır, eğer algoritmamızı görselleştirirsek şöyle gözükecektir.

Şimdi ise koşul durumlarının script içinde nasıl yazıldığına göz atalım.
cat kosul_ifadeleri.sh
if [[ $1 = 1 ]] #Değerin 1’e eşit olup olmadığını kontrol ediyoruz
then #1. durum sağlanırsa aktif hale girecek ve kendinden sonra ki komutu çalıştıracak.
echo "Değer 1'e eşit, sonuç kırmızı" #Eğer ilk komut çalışsaydı bu komut devreye girecekti.
elif [[ $1 = 2 ]]
then
echo "Değer 2'ye eşit, sonuç beyaz"
elif [[ $1 = 3 ]]
then
echo "Değer 3'e eşit, sonuç siyah"
else #Artık sağlanacak bir koşul kalmadı bu yüzden then ifadesi kullanmıyoruz.
echo "Değer [1,3] aralığına değil, sonuç sarı"
fi #Koşul durumunun bittiğini belirtiyoruz.
Karşılaştırma Operatörleri
Karşılaştırma operatörleri değişkenleri birbirleri ile kıyaslamaya yarar. Yazılan algoritma ve komutların akışını bu operatörler aracılığı ile sağlayabiliriz. Karşılaştırma operatörleri şu şekildedir:
-eq (equal-eşittir) ; == ; Değişkenlerin birbirine eşit olma koşulunu kontrol eder.
-ne (not equeal-eşit değil) ; != ; Değişkenlerin birbirine eşit olmama koşulunu kontrol eder.
-lt (less than-…’dan az) ; < ; Bir değişkenin diğer değişkenden küçük olma durumunu kontrol eder.
-gt (greater than-…’dan büyük) ; > ; Bir değişkenin diğer değişkenden büyük olma durumunu kontrol eder.
-le (less or eqaul-küçük veya eşit) ; <= ; Bir değişkenin diğer değişkenden küçük veya eşit olma durumunu kontrol eder.
-ge (greater or eqaul-büyük veya eşit) ; >= ; Bir değişkenin diğer değişkenden büyük veya eşit olma durumunu kontrol eder.
Örnek olarak karsılastırma_opt.sh
scriptini inceleyelim. Bu scripte 2 adet sayı değişken olarak veriliyor ve script değişkenleri 3 farklı if ile denetleyecek.
İlk if başlığında 2 adet sorgu olacak, “değerler eşit mi değil mi?”
İkinci if başlığında 3 adet sorgu olacak “ilk değer büyük mü? küçük mü? eşitler mi?”
Üçüncü if başlığında 3 adet sorgu olacak “büyük veya eşit mi? küçük veya eşit mi? değerler geçerli mi?”
Örnekleri tekrar ederken then ve fi kullanımlarını unutmayınız.
cat karsılastırma_opt.sh
if [[ $1 -eq $2 ]] #-eq yerine == gelebilir
then
echo "Birinci ve ikinci sayı birbirine eşit"
elif [[ $1 -ne $2 ]] #-ne yerine != gelebilir
then
echo "Birinci ve ikinci sayı birbirine eşit değil"
fi #İlk sorguyu kapatıyoruz
##
if [[ $1 -lt $2 ]]
then
echo "Birinci değer, ikinci değerden küçük."
elif [[ $1 -gt $2 ]]
then
echo "Birinci değer, ikinci değerden büyük"
else
echo "Birinci ve ikinci sayı birbirine eşit"
fi #İkinci sorguyu kapatıyoruz
##
if [[ $1 -ge $2 ]]
then
echo “Birinci değer, ikinci değerden büyük veya eşit.”
elif [[ $1 -le $2 ]]
then
echo “Birinci değer, ikinci değerden küçük veya eşit”
else
echo “Geçerli değerler giriniz...”
fi #Üçüncü sorguyu kapatıyoruz
And & Or Operatörleri - Ve Veya önermeleri
True/False işlemlerinde 1 doğru 0 yanlış anlamına gelmektedir. Eğer bir koşul parametresi doğru ise sisteme 1, doğru değil ise 0 değerini döndürür. Peki hazırladığımız koşul durumu içerisinde 1’den fazla koşul parametresi olmasını nasıl sağlarız? Bunu da and
ve or
operatörleri ile sağlarız.
Örnek and.sh
ile and operatörünü bir yaş sorgusu modeli ile ele alalım. And operatörü “&&” veya -a şeklinde kullanılır. And operatörü için girilen iki sorgunun da doğru (1) çıktısı almış olması gerekir.
cat and.sh
if [[ $1 -gt 0 && $1 -lt 18 ]]
then
echo "Girilen yaş reşitlik aralığında değildir"
else
echo “Girilen yaş reşitlik aralığındadır”
fi
Buradaki scriptimiz aldığı $1 değerini önce 0’dan büyük olup olmadığını sorguluyor, ikinci kısımda ise 18’den küçük olup olmadığını sorguluyor. Her iki sorguyu da karşılayan değerlere “Girilen yaş reşitlik aralığında değildir” çıktısı geliyor.
Örnek or.sh
ile or operatörünü basit bir oyun modeli ile ele alalım. Or operatörü “iki adet pipe işareti-||” veya -o olarak kullanılır. Or operatörü için girilen sorgulardan 1 tanesinin doğru (1) değerini almış olması yeterlidir.
or.sh
scriptini incelediğimizde girdiğimiz x değeri 5’den küçük olduğunda ya da 13’den büyük olunca oyunu kazanıyoruz. Bu koşulları sağlamadığında da kaybediyoruz.
cat or.sh
read -p "Bir değer giriniz = " x
if [[ ( $x -lt 5 || $x -gt 13 ) ]]
then
echo "Oyunu kazandınız!"
else
echo "Oyunu kaybettiniz!"
fi
Dosya Doğrulama Operatörleri
Yazdığımız scriptler ile dosyalarımızın durumlarını, erişim izinlerini, yazdırılabilir olup olmadıkları gibi dosya özelliklerini kontrol edip bunları otomatize edebiliriz. Bu bölümden itibaren if kullanımının ardından then satırını if ile aynı satırda yazacağız. if [[ $1 -eq 5 ]]; then şeklinde kullanacağız. “;” işareti parametreleri aynı satırda yazmamızı sağlayacak bu şekilde scriptlerimiz daha anlaşılabilir olacaktır.
İlk örnekte yazdığımız script değişken olarak girdiğimiz isimde bir dosya bulunup bulunmadığını kontrol edecer, girilen isimde bir dosya bulunmuyorsa, verilen isimde bir dosyayı oluşturur.
Öncelikle kontrolünü yapacağımız dosya ismini girelim sonra if bloğumuz dosyanın kontrolünü yapsın, ardından girilen isimde bir dosyanın bulunup bulunmadığını echo ile belirtsin.
dosya_kontrol_e.sh
scriptimizin içeriğini analiz edelim
cat dosya_kontrol_e.sh
read -p "Dosya ismi giriniz = " dosya
if [ -e $dosya ]; then
echo "$dosya adında bir dosya bulunmaktadır"
else
echo "$dosya adında bir dosya bulunmamaktadır."
sleep 0.5
echo "$dosya oluşturuluyor.."
mkdir $dosya
sleep 0.5
echo "$dosya oluşturuldu."
fi
if bloğunda olan -e parametresi dosyanın var olup olmadığını kontrol eden parametredir, diğer parametreler ise aşağıdaki şekilde kontroller yapar.
-e = Dosyanın olup olmadığını kontrol eder ; exist
-d = Dosyanın dizin olup olmadığını kontrol eder ; directory
-s = Dosyanın dolu olup olmadığını kontrol eder ; size
-r -w -x = Sırasıyla dosyanın okunabilir-yazdırılabilir-çalıştırılabilir kontrolünü sağlar ; read-write-execute
-f = Dosyanın olup olmadığını kontrol eder ve regular olup olmadığını kontrol eder. (regular dosya = -r -w -x yetkileri bulunduran demek)
Sıklıkla kullanılan operatörler bunlardır, bunların dışında farklı operatörler de vardır.
Farklı parametre kullanımı için dosya_kontrol.sh
scriptine göz atabilirsiniz.
Dosya İçerisine Metin Ekleme
Yazdığımız bir script ile dosya ismi belirtip o dosyanın içine girip yazılar ekleyebiliriz, bu işlemi gerçekleştirebilmek için dosyanın öncelikle regular olması gerekiyor.
(-r-w-x yetkilerine sahip olması). Yazacağımız script görseldeki gibi bir algoritmaya sahip olacak.

Öncelikle kullanıcıdan dosya ismini alıyoruz ve dosyasının regular file olup olmadığının sorgusunu yapıyoruz, ardından bu sorgudan alınan cevap ile bir başka sorgu daha oluşturuyoruz. Bu da bir if bloğunun altında if bloğunun oluşmasına neden oluyor, görsel içersinde bu durumu görebilirsiniz.
Eğer dosyamız yazdırılabilir değilse script görevini tamamlamadan çıkış yapar, dosya yazdırılabilir ise dosyanın içine girip istediğimiz şekilde değişiklik yapabiliriz. Dosya içersinde önceden bulunan metinler var ise yazdıklarımız o metinin altında yer alacaktır. Peki yazma işleminden çıkış nasıl yapacağız? Bunu da Ctrl+D işlemi ile yapıyoruz, eğer Ctrl+C ile yaparsak son yazdığımız satır silinebilir.
Burada koşul içinde koşul nasıl yazabileceğimize bir örnek veriyoruz.
dosya_metin_ekleme.sh
dosyası içeriği aşağıdaki gibidir.
cat dosya_metin_ekleme.sh
read -p “Dosya ismini giriniz = “ dosya
if [ -f $dosya ]; then
if [ -w $dosya ]; then
echo “Bu dosya yazdırılabilir. Çıkış için CTRL+D yapınız.”
cat >> $dosya
else
echo “Bu dosya yazdırılamaz.”
fi
else
echo “Dosya mevcut değil”
fi
Script yukarıdaki gibi yazdığımızda çalışacaktır, fakat sorguların ayırt edilmesi zor olacaktır. Script yazarken indentation kullanırsak, yazdığımız script içinde sorun çıktığında veya güncellemek gerektiğinde bunu çok daha kolay yapabiliriz. Burada bir birim boşluk bırakarak daha okunabilir dosya_metin_ekleme2.sh
isimli bir script yaptık. Yeni dosyayı analiz ettiğimizde:
cat dosya_metin_ekleme2.sh
read -p “Dosya ismini giriniz = “ dosya
if [ -f $dosya ]; then
if [ -w $dosya ]; then
echo “Bu dosya yazdırılabilir. Çıkış için CTRL+D yapınız.”
cat >> $dosya
else
echo “Bu dosya yazdırılamaz.”
fi
else
echo “Dosya mevcut değil”
fi
Case Kullanımı
Case ifadesi kullanılan değişkenin farklı değerler aldığında göstereceği eylemleri belirtmede kullanılan bir ifadedir. Örnek olarak değer x değişkeni A ise çıktısı B olur, C ise çıktısı D olur şeklinde. Case kullanımını daha hızlı kavramak için örnekler üzerinden ilerleyelim.
Örneklere case.sh
ve case2.sh
dosyaları üzerinden erişebilirsiniz.
cat case.sh
read -p “Bir plaka seçiniz (01,02,03,04) = “ plaka
case $plaka in
“01” ) #Plaka değeri 01’e eşit olduğunda çalışacak durum
echo “$plaka, Adana iline aittir”;;
“02” ) #Plaka değeri 02’ye eşit olduğunda çalışacak durum
echo “$plaka, Adıyaman iline aittir”;;
“03” ) #Plaka değeri 03’e eşit olduğunda çalışacak durum
echo “$plaka, Afyon iline aittir”;;
“04” ) #Plaka değeri 04’e eşit olduğunda çalışacak durum
echo “$plaka, Ağrı iline aittir”;;
* ) #Girilebilecek olası farklı değerler için
echo “01-02-03-04 plakalarından birini giriniz. “
esac #Case durumunun bittiğini belirtir
cat case2.sh
marmara=10;ege=03;akdeniz=01;ic_anadolu=06;karadeniz=05;dogu_anadolu=04;guneydogu_anadolu=02
read -p "Bir plaka seçiniz [01-02-03-04-05-06-10] = " plaka
case $plaka in
$marmara)
echo "$plaka, Marmara bölgesine aittir";;
$ege)
echo "$plaka, Ege bölgesine aittir";;
$akdeniz)
echo "$plaka, Akdeniz bölgesine aittir";;
$ic_anadolu)
echo "$plaka, İç Anadolu bölgesine aittir";;
$karadeniz)
echo "$plaka, Karadeniz bölgesine aittir";;
$dogu_anadolu)
echo "$plaka, Doğu Anadolu bölgesine aittir";;
$guneydogu_anadolu)
echo "$plaka, Güney Doğu Anadolu bölgesine aittir";;
*) #Girilebilecek olası farklı değerler için
echo "Geçerli plaka numarası giriniz... [01-81] ";;
esac
Dizi Kullanımları
Diziler birden çok veri barından yapılardır. Tüm meyvelerin isimlerinin bulunduğu bir yapı da dizidir, alışveriş listeniz de bir dizidir, sisteminize giriş yapan kullanıcıların IP bilgilerini otomatik ve düzenli şekilde içinde barındıran bir yapı da dizidir.
Dizileri şu şekilde tanıtırız; dizi_ismi = (‘deger1’ ‘deger2’ ‘deger3’ ...)
Kullanacağımız veri tipine göre verimizi tanıtlamalıyız. Örnekte görüldüğü gibi ‘deger‘ şeklinde belirtiyoruz ‘’ işareti kullanmadan da verimizi tanımlayabiliriz fakat veriniz birden fazla kelime içeriyorsa muhakkak “deger” ya da ‘deger’ şeklinde belirtmeliyiz.
Örnek olarak bir alışveriş listesi ve yapılacaklar listesi yazalım. Yazdığımız script bu listeleri, uzunluklarını, tek tek neler bulunduğunu bizlere söyleyecektir.
cat dizi.sh
alisveris_listesi=(“ekmek” ‘su’ bisküvi)
yapilacaklar_listesi=(‘oda toplama’ ‘klasorleri duzenleme’ ‘notlara goz atma’)
echo “–Alışveriş Listesi –“
echo “Listenin tamamı ve liste uzunluğu”
echo ${alisveris_listesi[@]} “||” ${#alisveris_listesi[@]}
echo “İlk ürün = “ ${alisveris_listesi[0]}
echo “İkinci ürün = “ ${alisveris_listesi[1]}
echo “Üçüncü ürün = “ ${alisveris_listesi[2]}
echo “–Yapılacaklar Listesi –“
echo “Listenin tamamı ve liste uzunluğu”
echo ${yapilacaklar_listesi[@]} “||” ${#yapilacaklar_listesi[@]}
echo “İlk ürün = “ ${yapilacaklar_listesi[0]}
echo “İkinci ürün = “ ${yapilacaklar_listesi[1]}
echo “Üçüncü ürün = “ ${yapilacaklar_listesi[2]}
Alışveriş listemizde veriler birer kelime olduğu için özgür bir şekilde onları tanıabildik fakat yapılacaklar listesindeki her veri iki kelimeden oluştuğu için ‘deger’ şeklinde belirtiliyorlar.
İkinci olarak dizi2.sh
örneğine bakabiliriz. Bu örnekte ise script’e 4 adet IP adres bilgisi ekliyoruz ve bu adresleri bir dizi içine tanımlıyoruz, ardından ise dizinin indexlerinden değerleri çekip ekrana yazıyoruz.
cat dizi2.sh
read -p "Birinci kullanıcı için IP bilgisini giriniz = " user1_IP
read -p "İkinci kullanıcı için IP bilgisini giriniz = " user2_IP
read -p "Üçüncü kullanıcı için IP bilgisini giriniz = " user3_IP
read -p "Dördüncü kullanıcı için IP bilgisini giriniz = " user4_IP
ip_adresses=(${user1_IP} ${user2_IP} ${user3_IP} ${user4_IP})
echo "IP Listesi"
echo "-- -- -- -- -- -- --"
echo "Kullanıcılar:"
echo ${ip_adresses[0]}
echo "---"
echo ${ip_adresses[1]}
echo "---"
echo ${ip_adresses[2]}
echo "---"
echo ${ip_adresses[3]}
Döngüler
While
Döngüler bir sürecin-durumun sürekli olarak kontrolünü yapar ve bu kontrol esnasında tanımlanan duruma erişim sağlanana kadar bu süreci devam ettirir. While komutu bu şekilde kontrol edilen durum doğru olana kadar tekrar eden bir rutin’dir.
Aritmetik bir örnek ile döngüler kısmını anlamaya çalışalım.
cat while.sh
x=0
while [ $x -le 15 ] #Döngüye tanımlanan koşul, x değerinin 15’ten küçük ve eşit olana kadar olan değerleri
do #Yapılacak işlemleri atama
echo “X değeri = $x”
x=$(( x+1 ))
sleep 0.5 #Her arttırma işleminden sonra yarım saniye bekle
done #Koşul sağlanınca durdurma kısmı
For
For komutu, işlemleri tanımlanan tekrar sayısı kadar yapılmasını sağlayan bir komuttur. Örnek olarak “girilen sayı kadar komutları tekrarla”, “dizin içinde bulunan dosya yazısı kadar ekrana IP değerini yazdır” gibi tekrar eden işlemleri yapmamızı sağlar.
for.sh
örneğinde x değeri ilk olarak 1 değerine gidip echo komutunu çalıştırıyor, ardından 2 değerine gidiyor ve tanımlanan son değere kadar işlemleri gerçekleştiriyor. Bu şekilde de for.sh
örneğinde 1’den 4’e kadar kullandığımız shell tipini ekrana bastırıyoruz.
cat for.sh
for x in 1 2 3 4 #{1..4..1} şeklinde de yazılabilir
do #İşlemlerin yapılmaya başlanacağı kısım
echo $SHELL
done # İşlemlerin sonlandırıldığı kısım
for2.sh
örneğinde ise x değerine 0 atayıp aritmetik işlem ile 4’e tamamlanana kadar aynı komutu tekrar çalıştıracağız(üstteki kullanımın farklı şekilde yapılması).
cat for2.sh
for (( x=0;x<=4;x=x+1 ))
do #İşlemlerin yapılmaya başlanacağı kısım
echo $SHELL | cut -c 6-9 # | ile iki komutu birleştirerek çalıştırdık
done # İşlemlerin sonlandırıldığı kısım
Şimdi de for3.sh
örneğinde konteyner içinde bulunduğumuz klasör ile etkileşime girerek for döngüsünü kullanalım. Bu örnekte bulunduğumuz dizin içinde var olan tüm (dizin, dosya…) yapıları listelenir.
cat for3.sh
for dosya in * #Buldugumuz dizindeki butun icerikler uzerinde gezmek icin
do
if [ -e $dosya ] #”Gidilen icerik mevcut mu?” sorgusu
then #Mevcut ise alttaki komutlari calistir
echo $dosya
fi
Yapılan sorgunun algoritması görseldeki gibidir.

Son olarak for döngüsü ile bulunduğumuz dizin içindeki dosyaları görüntülemeye yarayacak bir script yazalım.
cat dosya_görüntüleme.sh
echo “Dosyayı görüntülemek için y’ye basınız, diğer dosyaya geçmek için n’ye basınız”
for dosya in $(ls *.sh)
do
echo -n “$dosya görüntülensin mi? (y veya n) = “
read cevap
if [ $cevap == ‘y’ ]
then
cat $dosya
fi
done
Select
Select programı değişkenlerimizin, bir liste içinde bulunan değere göre işlemler yapmasını sağlar. Bu tanım case komutu ile benzerlik taşır.
cat select.sh
echo “Bir ürün seçiniz...”
select urun in Tişört Ayakkabı Saat #Değişkene atanabilecek değerler listesi
do
echo “$urun sepete eklendi.”
done
Şimdi select ve case programlarını beraber kullanacağımız bir script yazalım.
cat select2.sh
echo “Bir ürün seçiniz...”
select urun in Tisort Ayakkabi Saat #Değişkene atanabilecek değerler listesi
do
echo “$urun sepete eklendi.”
sleep 1
case $urun in
Tisort )
echo “V yaka $urun satın alındı”;;
Ayakkabi )
echo “Mavi $urun satın alındı”;;
Saat )
echo “Deri kayışlı $urun satın alındı”;;
* )
echo “Geçerli bir ürün giriniz...”;;
esac
done
Bu değişiklikler ile script daha interaktif bir hale geldi. Bu tip bir döngüden çıkmak için exit komutunu kullanmalıyız.
select3.sh
örneğinde, geçerli bir değer girene kadar sürekli çalışan bir script görüyoruz.
cat select3.sh
echo “Bir ürün seçiniz...”
select urun in Tisort Ayakkabi Saat #Değişkene atanabilecek değerler listesi
do
echo “$urun sepete eklendi.”
sleep 1
case $urun in
Tisort )
echo “V yaka $urun satın alındı”; exit;; #exit komutunu çalıştırmak için ... satın alındı” kısmından sonra ; ekliyoruz
Ayakkabi )
echo “Mavi $urun satın alındı”; exit;;
Saat )
echo “Deri kayışlı $urun satın alındı”; break;; #exit komutu yerine break komutu da kullanılabilir
* )
echo “Geçerli bir ürün giriniz...”;;
esac
done
Break ve Continue
select3.sh
örneğinde de gördüğümüz gibi exit ve break komutları ile işlemlerimizi, döngülerimizi durdurabiliyoruz fakat exit komutu aslında terminali kapatır, yaptığımız döngüyü kapatmıyor. Mesela Google Chrome kullanıyorsunuz ve Chrome tarayıcısını kapatmak için bilgisayarınızı kapatıp açıyorsunuz, bu şekilde örneklendirebiliriz.
Break komutu ise sadece döngüyü durdurur ardından terminal ile etkileşime girmez.
Şimdi bu işlemler için kullanacağımız break
komutunu inceleyelim.
cat break.sh
for x in {1..10..1} #(seq 2 2 100) olarak da yazabilirsiniz
do
if [ $x -eq 3 -o $x -eq 5 ]
then
break #x değerinin 3 ya da 5 olduğunda scripti durdurur
fi
pwd #x, 3 ve 5 olmadığı sürece pwd komutu bastır ve yarım saniye bekle
sleep 0.5
done
continue
komutu, break komutuna nazaran programı durdurmak yerine es vermesini sağlar. Yukarıdaki örnekte break yerine continue kullanırsak x değerinin 3 veya 5 olduğunda çalışmayı durdurması yerine programın 3 veya 5 değerlerinde durmasını sağlar, yani x değeri 3 ve 5 olduğunda o block çalışmayacak. Aynı örnek ile continue komutuna bakalım.
cat continue.sh
for x in {1..10..1}
do
if [ $x -eq 3 -o $x -eq 5 ]
then
continue #x değerinin 3 ya da 5 olduğunda script es verir.
fi
pwd #x, 3 ve 5 olmadığı sürece pwd komutu bastır ve yarım saniye bekle
sleep 0.5
done
Fonksiyonlar
Fonksiyonun matematikteki tanımına bakarsak, değişken sayıları girdi olarak kabul edip bunlardan bir çıktı oluşmasını sağlayan kurallardır. Bir işlem türüdür. Yani bash ortamında tanımladığımız fonksiyonlar girdiğimiz değerler üzerinde işlemler yapmamıza olanak sağlayacaktır. Sürekli yaptığınız bir matematik işlemi script içindeki bir fonskiyonu çağırarak yapabilirsiniz. Toplama, çıkarma, tarih-formatlama gibi aritmetik işlemler script içinde çok tekrar ediliyorlarsa bunları bir fonksiyon ile yapmak çok mantıklı olacaktır.
Gelin ilk örnek olarak “girilen değerin sürekli iki katını alıp on ekleme” fonksiyonunu tanımlayalım.
cat fonksiyon1.sh
read -p “Bir değer giriniz = “ x #Değişkeni kullanıcıdan alıyoruz
function matematik_fonk(){ #Fonksiyon başlığını giriyoruz ve içine komutları yazacağımız {} bloğunu açıyoruz.
let y=2*x+10 #Girilen değere işlemler yaparak yeni bir değer elde ediyoruz.
echo “$y” #Yeni değeri ekrana bastırıyoruz.
}
matematik_fonk #Fonksiyonu çağırıyoruz ve girilen değere göre işlemi ekrana döndürüyor.
İkinci örnekte ise bilgisayarımız ile temasa geçen fonksiyonları ele alalım.
cat fonksiyon2.sh
function tarih_ve_takvim(){ #date ve cal komutlarını bu fonksiyonuna tanımlıyoruz
date
cal
}
function dizinler_ve_kullanıcı(){ #dizinleri gösteren ve kullanıcı adı fonksiyonları
ls /
whoami
}
tarih_ve_takvim #Fonksiyonları çağırıyoruz.
dizinler_ve_kullanıcı
Kullanışlı Linux Komutları & Araçları
Son olarak scripting yaparken işimize yarayacak Linux komutlarını ele alacağız.
alias - Komutlara Takma İsim Atamak
Mesela bir firmada çalışan olarak her gün en az 4-5 kez kontrol edeceğiniz bir dosya bulunduğunu düşünelim ve bu dosyayı kontrol etmek için bulunduğunuz dizinden çıkıp dosyanın bulunduğu dizini yazıp ardından görüntülemek istediğiniz içeriği istediğiniz formatta yazdırmak için sürekli uzun uzun yazmak zorunda kalırız. Bunu yapmanın çok daha kolay bir yolu var, özellikle bunu pek çok kez yapmak istediğiniz zaman.
Örnek olarak /etc dizinin passwd adlı dosyasının ilk değerlerini kontrol etmek istiyorsunuz.
Bunun için de cat /etc/passwd | awk -F ':' '{print $1}'
komutunu yazmalısınız, bu oldukça uzun görünüyor. Bu komut dizisini her zaman girmek yerine gelin bu komut dizinini ikiye ayıralım ve takma isimler ile kolayca çağıralım. (awk
komutunu ileride detaylı bir şekilde göreceğiz.)
Takma isim atama formatı şu şekilde alias takma_ad=‘atamak istenen komut dizini’
Örnek komut dizinimizi iki parçaya ayıracağımızı söylemiştik, ilk parçası dosyayı görüntüleme ikinci parçası ise çıktıyı bir filtreden geçirip istediğimiz çıktıyı aldıracaktır.
alias showpasswd='cat /etc/passwd'
alias awkfilter='awk -F ":" "{print \$1}"'
showpasswd | awkfilter
Uzun olan komut dizinimizi işte bu kadar kolay bir şekilde daha kullanışlı bir hale getirdik.
Tanımlanan alias değerlerini unalias takma_isim
komutuyla kaldırabilirsiniz.
awk
awk komutu en fazla kullanılan yazı işleme araçlarından biridir, aslında awk bir programlama dilidir. Awk “. , : ; |” gibi bölümlere ayırılmış dosyaların istediğimiz şekilde çıktılarını almamızı sağlar.
cat, head, tail gibi yazı düzenleme komutlarını Linux 101 eğitiminden hatırlıyorsunuzdur, bu komutlar ile aldığımız çıktıları awk ile belirttiğimiz filtrelerden sonra istediğimiz çıktıyı elde etmemizi sağlar. awk kullanımı aşağıdaki gibidir:
awk ‘{print $ıstenen_deger}’ awk.txt
şeklinde kullanılır, eğer awk.txt dosyasının tüm satırlarının birinci değerini istersek awk ‘{print $1}’ awk.txt şeklinde yazmamız gereklidir ve çıktımız da şöyle olacaktır:
1
4
7
Eğer 1 yerine 2 yazarsak, bu sefer ikinci sütunu getirecektir fakat bu tarz işlemleri cut komutu ile yapmak daha kolay olacaktır bu yüzden awk’yı işimize yarayacak şekilde kullanmaya başlayabiliriz. cat ogrenciler.txt komutu ile karşımıza 20 adet rastgele şekilde oluşturulmuş öğrencilerin bilgileri gelecektir. awk komutu ile bu dosyadan istediğimiz değeri çekelim şimdi.
cat ogrenciler.txt | awk '{print $1}'
dersek bütün veri listesi tekrar karşımıza gelecek. Gördüğünüz gibi veriler birbirlerinden “,” işareti ile ayrılmıştır eğer biz verileri parçalamazsak bütün veriler bir kalıp gibi olacaktır ve kullanılamaz olacaklardır.
awk komutuna “bana bu dosyayı virgülleri dikkate alarak parçalara ayır ve öğrencilerin ismi olan ikinci sütun değerlerini ver” demenin yolu ise -F (file separator)
parametresi ile dosyayı ayırmak olacaktır.
cat ogrenciler.txt | awk -F ',' '{print $2}'
komut dizinini gönderdiğimizde bize 20 öğrencinin de adını getirecektir eğer 2 yerine 6 değerini girersek bütün öğrencilerin IP değerleri karşımıza çıkacaktır. mockaroo isimli websitesi üzerinden random datalar elde edip kendi örneklerinizi yazabilirsiniz.
cat ogrenciler.txt | awk -F ',' '{print $2, $3, $4, $5, $6}'
Şeklinde ise baştaki sıra numaralarını dahil etmeden bütün veri değerlerini çekebiliriz.
cat ogrenciler.txt | awk -F ',' '{print "Ogrenci:" $2, $3,"| mail:" $4,"| IP:" $6}'
Formatında ise bilgileri listeleyerek elde edebiliriz.
cut
cut komutu için awk komutunun 1-2 özellik eksik hali diyebiliriz fakat metinler ile istediğimiz şekilde oynamamız için güçlüdür. cut isminden belli olacağı gibi dosyalardan veri kırpmamızı sağlar.
cut -d ',' -f2,3 ogrenciler.txt
şeklinde girdiğimiz zaman öğrenci setimizden “isim,soyisim“ şeklinde bizlere değerleri verecektir.
sed
sed komutunun açılımı stream editör şeklindedir, bu komut aldığımız değerlerin akışını değiştirir yani istediğimiz değeri istediğimiz değer ile değiştirebiliriz. İsterseniz sed komutu ile ogrenciler.txt dosyamızda bulunun Female, Male bilgilerini Kadın, Erkek şeklinde değiştirelim ardından değişmiş halini öğrenciler_tr.txt dosyasına aktaralım böylece ilk dosyamıza zarar vermeyelim.
sed 's/Female/Kadin/' ogrenciler.txt >> ogrenciler_tr.txt
Şeklinde tanımladıktan sonra ogrenciler_tr dosyasını elde ediyoruz, gelin şimdi de ogrenciler_tr’de bulunan erkek öğrencilerin verilerini düzenleyelim ve örneği tamamlayalım.
sed 's/Male/Erkek/' ogrenciler_tr.txt
Burada bahsetmek istediğim bir şey var arkadaşlar, bu eğitimi tamamladıktan sonra laboratuvar ortamında nano
komutu ile örnek dosyalarını kontrol ederken Türkçe karakterler laboratuvar ortamında sorunlar çıkartıyordu. Ben de sed komutu ile 50’den fazla dosyada ki tüm Türkçe küçük ve büyük harfleri saniyeler içerisinde aşağıdaki gibi değiştirebildim.
sed -i 's/Türkçe karakter/İngilizce karakter/g' *
grep
Grep komutunu Linux 101 eğitimi içerisinde işlemiştik fakat tekrar hatırlatmak amacı ile bir üstünden geçelim çünkü ilerleyen komutlarda grep komutunu da kullanacağız.
Grep, girilen değerin aranan dosya içinde olup olmadığını bize gösterir. Örnek olarak şöyle ele alalım, ogrenciler.txt dosyası içerisinde mail adresinde “.com” uzantısı bulunan öğrencileri ayrı bir dosyada tutalım.
grep '.com' ogrenciler.txt > ogrenciler_com.txt`
olarak bunu gerçekleştiririz.
Eğer grep komutunu -c (count)
parametresi ile gönderirsek bize .com uzantısı kullanan öğrenci sayısını söyleyecektir.
grep -c '.com' ogrenciler.txt
Şimdi ise diğer komutları da kullanarak ogrenciler.txt
dosyasını virgüllerinden ayırarak IP adresleri 14 ile başlayan öğrencileri alalım.
cat ogrenciler.txt | awk -F ',' '{print $6}' | grep '14?*'
Başka bir örnek olarak da history_kontrol.sh
adlı dosyayı ele alalım. Bu scripte bakacak olursak
cat history_kontrol.sh
date >> history_kontrol.txt ; cat history.txt | grep 'sudo' | nl >> history_kontrol.txt
date >> history_kontrol.txt ; cat history.txt | grep 'root' | nl >> history_kontrol.txt
Şeklinde karşımıza çıkan bu örnek öncelikle çalıştırıldığında history_kontrol.txt
dosyasına işlemin gerçekleştiği gün ve saati yazdırıyor. Ardından history
komutu ile önceden girilen komutların yazdırıldığı history.txt dosyası içinde sudo
veya root
gibi önemli parametrelerin kullanılıp kullanılmadığını grep
komutu ile filtreliyor.
wc
wc komutu ise bir dosya içinde bulunan satır sayısını, kelime sayısını ve byte değerinin ne kadar olduğunu sıralı bir şekilde bize gösterir.
cat ogrenciler.txt | grep 'Female' | wc
sorgusunu gönderdiğimiz zaman bize 12 12 715 değerlerini döndürecektir. Bu değerler ise dosyamızda 12 satır, 12 kelime ve toplamda 715 byte olduğunu bize söyler. -l parametresi ise direkt bize kaç kere geçtiğini gösterir. Böylece ogrenciler.txt dosyasında 12 adet “Female” ifadesini bulunduran satır mevcuttur.
Başka bir örnek olarak ogrenci_sayisi.sh
dosyasına bakabiliriz. Bu örnek öğrenci sayısının 20’den az olduğu durumlarda bize uyarı verecek. Örnek esnasında cut
ve wc
komutlarını beraber kullanacağız, bu scriptte önemli olduğuna inandığım başka bir konuya da değineceğiz. “Komut dizini çıktısını değişkene atama”.
cat ogrenci_sayisi.sh
sayi=`cat ogrenciler.txt | wc | cut -d" " -f6`
#wc komutu ile ogrencilerin sayisini aldik
#cut ile wc çıktısının ilk degerini aldik
#Degiskenden sonra ` ` ifadesi ile komut dizinini "sayi" degiskenine atadik
#Komut dizinin cıktısı 19 oldugu icin "sayi" 19'a esit oldu
if [ $sayi -le 20 ]; then
echo "Yeterli sayida ogrenci yok."
else
echo "Yeterli sayida ogrenci var."
fi
tr
tr komutu, sed komutu gibi dosya içeriklerinde bulunan verileri kontrol etmemize yarayan bir komuttur. Kullanım şekli:
cat dosya | tr '[a-z]' '[A-Z]'
. Bu komut dizininden sonra ekrana bastırılan bütün değerler büyük harfler ile döndürülecektir.
ogrenciler.txt
dosyamız üzerinden gidersek,
cat ogrenciler.txt | tr '[a-z]' '[A-Z]'
ya da
cat ogrenciler.txt | tr '[:lower:]' '[:upper:]'
şeklinde kullanabiliriz.
Başka bir örnek olarak da ogrenciler.txt dosyasında virgüllerin yerlerine boşluk değerlerini atayalım.
tr ',' ' ' < ogrenciler.txt
sort
sort
komutu sayılar değerleri küçükten büyüğe, kelimeleri ise alfabetik olarak sıralama yarayan bir komuttur.
öğrenciler.txt dosyamızı öğrencilerin isimlerine göre alfabetik sırada sıralanmış bir şekilde çıktısını almak istersek
cat ogrenciler.txt | awk -F ',' '{print $2,$3,$4,$5}' | sort
şeklinde alabiliriz. siparisler.txt dosyamız üzerinden de başka bir örneği ele alalım şimdi.
cat siparisler.txt
Dediğimiz zaman 20 satırlık müşteri, ülke, para birimi, mail, tutar şeklinde 6 birime bölünmüş bir metin dosyası karşımıza çıkacak. Önce awk ile tutar
para birimi
müşteri
şeklinde bir çıktı alalım ve sort
komutu ile az tutardan fazla tutara olacak şekilde sıralayalım.
cat siparisler.txt | awk -F ',' '{print $6, $3, $1}' | sort
uniq
uniq, komutu unique sözcüğünden gelmektedir. Bu kelimenin Türkçe karşılığı ise “benzersiz”. Uniq komutumuz dosyalar içinde bulunan tekrar eden satırları ayıklamamızı sağlar. Gelin şimdi öğrendiğimiz komutlar ile bu metini parçalara bölüp uniq ile sayılarını öğrenelim. Eğer siparisler.txt dosyamızdaki fiyatlar değerlerine bakıcak olursak 20 adet tutar var fakat bunların hepsi farklı farklı tutarlar değil.
cat siparisler.txt | awk -F ',' '{print $6}' | sort | uniq
sorgusunu gönderdiğimiz zaman bize tüm siparişlerin tutarları küçükten büyüğe sıralanmış olarak gelecek. Bu sorgu içinde bulunan tutarların kaç kez geçtiğiniz öğrenmek için uniq
komutuna -c(count) parametresini göndermemiz gerekecektir.
cat siparisler.txt | awk -F ',' '{print $6}' | sort | uniq -c
sorgusunu gönderdiğimiz zaman her tutarın kaç kez tekrar ettiğini göreceğiz.
nl
kısaltması nl olan number of lines komutu, çıktılarımızın satır başlarına kaçıncı satırda bulunduklarını yazarak liste işlemlerinde kullanılan bir komuttur.
cat siparisler.txt | nl
dediğimiz zaman, satır başlarında numaralar eklenmiş şekilde bir çıktı alacağız.
cat siparisler.txt | nl > siparisler_nl.txt
şeklinde numaraların eklemiş olduğu bir dosya oluşturabiliriz.
curl
Curl aracı bir web sayfasını HTTP protokolü ile elde etmemizi sağlar. Curl’i sanal makinemize kurduktan sonra örneklere geçebiliriz.
apt update ; apt install curl -y
Peki curl aracını ne için kullanabiliriz? Websitemizin sağlıklı bir şekilde çalışıp çalışmadığını curl ile çekerek kontrolünü sağlayabiliriz, eğer curl’i içeren bir script yazarsak belirli aralıklar ile websitemizin HTML dosyasını çekeceğiz ve 1 saat boyunca curl bir hata ile karşılaşınca bize haber verecek.
cat curl.sh
for y in {1..60..1}
do
curl -s www.github.com #-s ile HTML dosyasini sessiz modda calistirarak ekrana bastirmadik
if [ $? == 0 ];then
echo "github.com ayakta!"
else
echo "github.com ayakta değil!"
fi
sleep 10
done
Konu tekrarı, kısa sınav
seçeneklerden doğru olanları seçtikten sonra Gönder butonuna basınız. Sonuçları doğru ve yanlış görebilirsiniz.
“Her” veya “Hepsi” anlamını taşıyan kabuk karakteri nedir?
- ( ) @
- (x) *
- ( ) #
- ( ) ?
Kabuk üzerinde aktif olan bir sistem değişkeni nasıl kaldırılır
- ( ) alias
- ( ) env
- ( ) export
- (x) unset
Bir script için 0 (sıfır) numaralı argüman nedir?
- ( ) shell türü
- (x) scriptin kendi ismi
- ( ) verilen ilk argüman
- ( ) kullanıcı adı
Script içersinde klavyeden girdi sağlayan komut hangisidir?
- ( ) alias
- (x) read
- ( ) cat
- ( ) echo
if sorgulamasını sonlandırmak için hangi komut kullanılır?
- (x) fi
- ( ) elif
- ( ) if
- ( ) then
Elimizde bir argüman listesi olsun “programlar = ‘python,C,java,go’ programlar[2] değeri nedir?
- ( ) python
- ( ) c
- ( ) go
- (x) java
Hangi read komutu parametresi yazılan değerlerin ekranda görüntülenmesini engeller?
- ( ) -p
- ( ) -d
- (x) -s
- ( ) -h
Aşağıdaki dosya operatör parametrelerinden hangisi yanlış tanımlanmıştır?
- ( ) -e “Dosyanın var olup olmadığını sorgular”
- (x) -f “Dosyanın boyutunu sorgular”
- ( ) -d “Dosyanın dizin olup olmadığını sorgular”
- ( ) -x “Dosyanın çalışıp çalışmadığını sorgular”