Linux Bash Script Yazım Teknikleri 1.Bölüm Genel Kavramlar

Merhaba dostlar,
Bu makalemizde sizlerle birlikte Linux Shell kabuğu üstünden BASH script yazma ile ilgili temel detayları paylaşıyor olacağım.Gelin isterseniz BASH Script’inin özetlemek gerekirse özgeçmişine bakalım;
Bash, Brian Fox tarafınca GNU Projesi için Bourne kabuğunun yerine parasız bir yazılım olarak yazılmış bir Unix kabuğu ve komut dili olarak ortaya çıkmıştır.İlk olarak 1989’da piyasaya sürülmüştür.Linux dağıtımında ve Apple’ın MacOS Mojave ve önceki sürümlerinde varsayılan giriş kabuğu olarak yaygın bir halde kullanılmıştır. Günümüzde Windows 10 için de kullanılan bir sürümü mevcuttur.
Bash, çoğu zaman kullanıcının eylemlere yol açan komutları yazdığı bir metin penceresinde çalışan bir komut işlemcisidir. Bash ek olarak kabuk betiği isminde olan bir dosyadaki komutları okuyabilir ve yürütebilir. Tüm Unix kabukları benzer biçimde, dosya adı globbing (joker karakter eşleştirme), boru tesisatı, burada belgeler, komut değişiklik yapma, değişkenler ve durum testi ve yineleme için denetim yapılarını destek sunar. Anahtar kelimeler, sözdizimi, dinamik olarak kapsamlandırılmış değişkenler ve dilin öteki temel özellikleri sh’den kopyalanır. Öteki özellikler, mesela tarihçe, csh ve ksh’den kopyalanır. Bash POSIX uyumlu bir kabuktur, sadece bir ekip uzantıları vardır.
Bash komutu sözdizimi, Bourne kabuğu komut sözdiziminin bir üst kümesidir. Bash, öteki özellikler içinde küme ayracı genişletme, komut satırı tamamlama, temel hata ayıklama ve kural dışı işleme (tuzak kullanarak) destek sunar. Bash, Bourne kabuğu komut dosyalarının büyük çoğunluğunu, değişim yapılmadan, Bash’te değişik şekilde yorumlanan saçak sözdizimi davranışına giren yada daha yeni bir Bash yerleşikine uyan bir sistem komutunu çalıştırmaya çalışırken, vb. Çalıştırılmadan kural dışı olarak uygulayabilir. Bir kullanıcı etkileşimli bir komut kabuğundaki sekme tuşuna bastığında, Bash otomatikman komut Bash’in sözdiziminde Bourne kabuğunda tamamlanmamış olan birçok uzantı vardır. Bash, harici işlemleri oluşturmadan tamsayı hesaplamaları dahil bir oldukca işlemi yapabilirsiniz
Linux ve UNIX sistemlerde yaygın kullanılan bazı kabuk(Shell) türleri şu şekildedir;
Bourne Shell: İlk kullanılan UNIX kabuğudur ve bir çok UNIX dağıtımı ile beraber öntanımlı kabuk olarak dağıtılmaktadır.
Korn Shell: Korn Shell SH ile uyumlu, birçok ek programlama özelliği de içeren bir kabuk türüdür.
Bourne Again Shell: Kullanım kolaylığı bakımından en oldukca rağbet gören bash, sh ve ksh uyumluluğunu korurken, bilhassa etkileşimli kullanıma yönelik (komut tamamlama, benzer biçimde) birçok yenilik de ihtiva eder.
C Shell: Berkeley Üniversitesi’nde geliştirilen csh’in C diline benzer bir programlama yapısı vardır. Bilhassa programcılar tarafınca tercih edilir.
TCSH: csh’ın birazcık geliştirilmiş hali diyebiliriz.
Linux üstünde kullanıcının işletim sistemini kullanımı için temel iki yol vardır. Bunlardan biri GUI olarak adlandırdığımız grafik arabirimler diğeri de konsol üstünden yapabileceğimiz komut satırı yönetimidir.Kabuk programlamada en temel fonksiyon esasında konsol üstünden verilen komutları belirli bir derleme üstünden çalıştırarak çıktı elde edilmesi faliyetidir. Daha mütevazi anlatmak gerekir ise gün içinde user yada sistem tabanlı konsol işlemlerimizi bir dosya içinde derleyerek bir shell script yazmış oluruz. Heralde belirli amaçlara yönelmiş programlar için fonksiyon, dizi , döngüler benzer biçimde daha üst düzey yapılar kullanmamız gerekebilir ki bu makalede anlatacağımız yapılardan bir tanesi olan “bash” bu tarz şeyleri fazlasıyla sağlamaktadır.
Kod yazmaya başlamadan bir ek daha yapalım. Makalemiz içinde yazdığımız script örneklerini sizlerde herhangi bir Linux sürümü içinde yazıp çalıştırabilirsiniz.Yanlız her işlem için konsolu tercih ediyor iseniz Nano ve Vi benzer biçimde konsol tabanlı editörleri de kullanmayı deneyebilirsiniz.
Bash Shell hakkında birazcık konuştuktan sonrasında isterseniz küçük küçük uygulamalara girelim.
Ben scriptleri Kali Linux üstünde yazmak istediğimden dolayı bu işletim sisteminin kernel tarafında çalışacağım isterseniz siz değişik bir Linux sistem üstünde çalışabilirsiniz.Kali makinama SSH bağlantımı yaparak terminal oturumunu açıyorum.

Ssh bağlantımızı yaptıktan sonrasında kernel içinde geçerli Shell tiplerini “cat /etc/shells” komutu ile görebilmekteyiz.Yukarıda anlattığım kabuk türleri içinde kullanacağımız kernel katmanı bash olacağından dolayı örneklerimizi bu shell üstünden konumuzda şekillendireceğiz.

Sistemimizin default olarak hangi Shell kabuğunu kullandığını öğrenmek istiyor isek bunun için komut satırına “which bash” yazarak öğrenebiliriz.Sistemimiz default olarak “/.bin” dizinin altında çalıştırılan bash kabuğunu kullanmakta.

Peki Bash shell’inin bulunmuş olduğu Bin dizini ne işe yaramaktadır.Bin dizini olması ihtiyaç duyulan şartlarla dolu komut dosyalarını ihtiva eder.Bunun haricinde Başlıca alt dizinler /boot, /dev, /etc, /home, /initrd, /lib, /lost+found, /misc, /mnt, /opt, /proc, /root, /sbin, /tmp, /usr ve /var dizinleridir.Bunlar Linux Kernel yapısının çalışmasını ve faliyetini düzenleyen dizin grubudur.

Script yazmadan ilkin sistemimizde ister Masaüstünde iserseniz başka bir dizinin altında bir dizin oluşturarak işe başlıyoruz.Doğal olarak bu Scriptleri çalıştırmak için ilk olarak Root yetkisine haiz hesabımız ile giriş yapmamız lüzumlu.Bunun için Sudo –S komutu ile root yetkisini aldıktan sonrasında “mkdir BashScript” komutunu yazarak bir tane dizin oluşturuyoruz.Sonrasında ls komutu ile dizinimizin oluşup oluşmadığını denetim ediyoruz.

BashScript dizinimizi oluşturduktan sonrasında bu dizinin içine bir tane ScriptOrnek dosyası oluşturuyoruz.Doğal olarak bunun akabinde bu dosya içinde yetkili şekilde işlem yapabilmek için )script çalıştırma) dosya izinlerini chmod +x yetkisini vererek içinde emek verme alanımızın yetkilendirilmesini sağlıyoruz.

Sonrasında Nano editörü ile oluşturduğumuz dosya içine giriyoruz.

Dosyamıza lüzumlu izinleri verdikten sonrasında nano editörü ile dosyamızı açıyoruz.Buradaki komutlar default gelmemekte.Bu sizi yanıltmasın.Yazdığım komutları size detaylı şekilde açıklayacağım.
Bildiğiniz benzer biçimde eğer yazılım diline birazcık aşina iseniz belirli değişkenler ve operatörler vardır.Bir script yazar iken bu script türüne gore başlangıç komutları mevcuttur. Script yazdığımızdan dolayı bu biçim scriptlerin devamlı başlangış noktasında #! /bin/bash komutunu kullanmamız gerekmektedir.Bunun sebebini açıklamak gerekir ise;
#! /bin/bash
#!:Yazmak istediğiniz herhangi bir script dosyasını yazmaya başlamadan ilkin her daim bu ifadeyi kullanmanız gerekmektedir.Bunun sebebi ise Shebang olarak bildiğimiz bu başlangıç karakterinin bizim hangi bash programını kullanıcak isek onu yazmamız için lüzumlu olan dizindir.
/bin/bash: Şimdi burdaki en eleştiri nokta hangi bash yazılımı kullandığımızı bu bölümde belirtmemiz gereklidir.Niçin diye sorulucak olursa eğer bunu belirtmez isek değişik sistemlerde bu derlediğimiz Script çalışmayabilir.Doğal olarak Linux sisteminizin hangi bash yazılımını kullandığını birazcık üstte “which bash” komutu ile görebileceğinizi söylemiştim.Heralde bunu yazmasanızda kısaca (#!—null) olarak bırakırsanız da yazdığınız script çalışabilir. Yanlız yazdığınız Script başka bir sistemde çalıştırılmak istendiğinde hata verme ihtimali vardır. Bu yüzden bu bash dizinini yazmayı kesinlikle bir alışkanlık haline getirmenizde yarar olduğu düşüncesindeyim.
Echo komutuna gelirsek.Aslen C# da ilk derslerde bilirsiniz.Derlemek ve insert ettiğimiz veriyi terminale yazmak için “console.writeline (“Merhaba Dünya”); yazdığınızda ve Ctrl+F5 ile derlediğinizde konsola Merhaba Dünya iyi mi yazıyor ise herhangi bir komutu derleyip ekranda göstermek istediğinizde “echo” komutunu kullanırız.Bunu neredeyse tüm scriptlerimizde değişkenlerin ve öteki değerlerin terminalde görünmesi için devamlı kullanacağız.

Nano editör ile yazdığımız (echo “merhaba Çözümpark” ) yazdıktan sonrasında Ctrl+X ile kayıt ettikten sonrasında sıra geldi yazdığımız ilk temel ayarları bulunan scriptin çalıştırılmasına.Bunun için ilgili dizin üstünde iken (./script adı) olarak çalıştırabiliyoruz.Peki bunu niçin bu şekilde çalıştırmaktayız.Bunuda ek olarak detaylandırmak isterim.
Linux Sisteminde komut satırının emek verme mantığında,eğer bir script yada uygulama derlemek istediğinizde kullandığınız sistem içinde çalıştırdığınız uygulamayı path içinde bulunan klasörlerde tarayacaktır.Bu sebeptendir ki bulunulan klasör ifadesi olarak “./script dosyası” işaretiyle gerçekleştirilir.
Nano editör ile yazdığımız scripti çalıştırdıktan sonrasında ekran satırına gördüğünüz suretiyle yazdığımız ileti gelmiş bulunmaktadır.
Peki ben bunu düzgüsel Linux sistemi içinde herhangi bir methoda gerek kalmadan iyi mi çağırabilirim ?

Sözgelişi dizin içinde çağırdığımızda gördüğünüz benzer biçimde oldukça rahat şekilde scriptimiz çalışmakta.Fakat dışarıya çıktığımızda bu dizin içindeki Script yolunu bulamadığından çalışmamakta.Bununda oldukça kolay bir yöntemi var adım adım bunu irdeleyelim.

Ilk olarak terminalden “/usr” dizinine geçerek işlemimize başlıyoruz.Peki niçin bu dizine geldik ? USR dizinin görevi mühim sistem dosyalarını tutmasıdır. Bu bölüm genel anlamda en kalabalık dizindir, zira yeni kurulan tüm programlar buraya konulmaktadır.Bunun içinde bizi ilgilendiren 2 alt dizin vardır.
Bunlar;
Bin-Kullanıcı komutlarını barındıran dizin.
Sbin-Admin komutlarını barındıran dizin.

Şimdi bizim masaüstümüzde bulunan dizini direk usr dizinin içine bulunan bin dizinine alıyoruz.

Terminale “/cd /bin” yazarak Bin dizinin içine oluşturduğumuz script dosyasının eklendiğini görüyoruz.
Gördüğünüz benzer biçimde artık Linux dizinlerinden herhangi bir kısmında scripti çalıştırabiliyoruz.
Değişkenler Nedir ve Iyi mi Kullanılır ?
Değişken dediğimiz fonksiyonlar alanındaki hafızasında kıymet tutan gerektiğinde referans olarak kullanılabilen yada gerektiği zamanda değişebilen araçlardır.Hafızada bir miktar yer ayırıp içinde bir kıymet tutarsınız ve ihtiyacınız olduğunda başka bir bellek alanı kullanmadan değişkenin kıymetini değiştirip yine kullanabilirsiniz. Oldukça kullanışlı bir yapı olan değişkenlerin kullanımında uyulması ihtiyaç duyulan bazı kurallar bulunmaktadır. Bu kurallara kesinlikle uymalısınız.
Bir değişkene atıfta bulunup referans göstermek istediğinizde, değişken isminin başına ( $ ) işareti koymanız yeterlidir.Bilhassa sistem ve kullanıcı değişikenlerinde buna dikkat edilmesi gerekmektedir.
Sistem Değişkeni | Komut Anlamı | Değişken Kıymet Türünü Görüntülemek İçin Kullanılan Parametre |
BASH_VERSION | Holds the version of this instance of bash. | echo $BASH_VERSION |
HOSTNAME | The name of the your computer. | echo $HOSTNAME |
CDPATH | The search path for the cd command. | echo $CDPATH |
HISTFILE | The name of the file in which command history is saved. | echo $HISTFILE |
HISTFILESIZE | The maximum number of lines contained in the history file. | echo $HISTFILESIZE |
HISTSIZE | The number of commands to remember in the command history. The default value is 500. | echo $HISTSIZE |
HOME | The home directory of the current user. | echo $HOME |
IFS | The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is <space><tab><newline>. | echo $IFS |
LANG | Used to determine the locale category for any category not specifically selected with a variable starting with LC_. | echo $LANG |
PATH | The search path for commands. It is a colon-separated list of directories in which the shell looks for commands. | echo $PATH |
PS1 | Your prompt settings. | echo $PS1 |
TMOUT | The default timeout for the read builtin command. Also in an interactive shell, the value is interpreted as the number of seconds to wait for input after issuing the command. If not input provided it will logout user. | echo $TMOUT |
TERM | Your login terminal type. | echo $TERM export TERM=vt100 |
SHELL | Set path to login shell. | echo $SHELL |
DISPLAY | Set X display name | echo $DISPLAY export DISPLAY=:0.1 |
EDITOR | Set name of default text editor. | export EDITOR=/usr/bin/vim |
Yukarıda gördüğünüz sistem değişkenlerini sizde kendi scriptinize yaptığımız uygulamalardaki benzer biçimde ekleyebilir çalıştırabilirsiniz.

Sistem ve kullanıcı değişkenlerine örnek olarak bir tane yukarıdaki Description kısmında yer edinen değişkenleri yazarak CTRL-X ile kayıt ediyoruz.

Gördüğünüz benzer biçimde sistem değişkenlerini terminale yazdırdık.Yanlız burda şu nokta var bundan önceki durumda biz yazdığımız scripti bin klasörüne usr dizininden eklediğimiz için eskisi çalışıcaktır.Scripti her kayıt ettiğinizde kısaca güncellediğinizde usr dizinine gidip cp komutu ile kopyalamanız gerekmektedir.

Kullanici değişkeni ise siz kullanıcı olarak girdiğiniz verilerin ekrana yansımasıdır.Esasında bu aşamada read dediğimiz değişkeni Numara kısmına set ederek kullanıcının terminal üstünden insert etmesini sağlayarak çıkan sonucu derliyoruz.

Numaralar kısmında girdiğimiz sayıyı Numara değişkenine atayarak sonucu direk yazdırdık.

Diyelim ki terminal üstünden insert ederek bir kullanıcı adı ve gizyazı yazdırmak istiyorsunuz.Bunun için “read –p” parametresini kullanırız.Bunu kullanmamızdaki amaç yazım dizilimini tutarlı şekilde kalmasını sağlamak.

CTRL+X ile kayıt edip terminalden scripti çağırdığımızda kullanıcı verilerini insdert ederek ekranda bu yazılan verilerin çıktısını yatay şekilde alabiliyoruz.

Eğer girilen veride şifrenin giriş yapar iken görünmemesini istiyor isek “read –sp” parametresini ekleyebiliriz.
Bash ile ilgili dizilerin kullanımına ilişkin ergonomik örnekleri bulmak zor olsa gerek. Bende temel olarak bir kaç değişik uygulama ile bu mevzuda sizlere detayları pekiştiricek çeşitli temel uygulamalar göstereceğim.Mesela, sisteminizde hakkaten hiçbir şey yapmayan sadece matematiksel serileri hesaplamak için dizileri kullanan oldukca sayıda komut dosyası oluşturabiliriz. Esasında dizilerin kullanım zorluğunun sebeplerinden bir tanesi dizilerin oldukça karmaşık yapılar olmasıdır. Dizilerin kullanılabileceği en ergonomik örneklerin, diziler kullanılarak sisteminize aslına bakarsan uygulanmış bulunduğunu, sadece daha düşük bir düzeyde, bir çok UNIX komutunun yazıldığı C programlama dilinde bulunduğunu eğer birazcık iç sistemlerin yazılım mantığını karıştırırsanız görmüş olacaksınız. Buna iyi bir örnek Bash geçmişi yerleşik komutudur. İlgilenen okuyucular Bash kaynak ağacındaki yerleşik dizinini denetim edebilir ve bu bileşenleri derlerken işlenen kaynak dosyasına bakabilirler.
Peki Dizi kısaca Array terimi nedir bundan anlatmak gerekir ise array dediğimiz yapının temel mantığı aynı tip verilerin birbiri arkasına tanımlanmasıdır. Esasında dizi yapısını bir büyük kümeye benzetebiliriz.Bunun içindeki aynı tip verilere teker teker erişmek yerine bir takım içinde atadığımız tek bir isimle erişmek için kullandığımız bir fonksiyondur. Bir dizinin tüm elemanları bellekte peşpeşe saklanırlar. Diziler kullanılarak, aynı isimle birden fazla değişkene erişilebilir ve işlem yapılabilir. Diziler tek ya da oldukca boyutlu olarak tanımlanabilir ve dizi boyutu ihtiyaca gore ayarlanabilir.char, int, float ve double olarak tanımlanabilen dizilerde yalnız aynı veri türünden değişken değerleri yer alabilir.Dizileri tek boyutlu ve oldukca boyutlu olarak iki kısma ayırabiliriz. Tek boyutlu dizilere sayı dizilerini ve vektörleri örnek verebiliriz. Oldukça boyutlu dizilere ise matrisleri örnek verebiliriz.
Array Mantığına örnek bir uygulama yapalım;

Örnek olarak kullandığımız script mantığına bakar isek 6 tane sayı değişkenini atayarak toplam dizin ve ona atanan indexkleri kapsayan bir uygulama yazdık.Dikkat ederseniz array yapısı kullanır iken $ {Arr [*]} benzer biçimde yapılarda “*” yerine “@” işaretinin kullanılabileceğini ihmal etmeyin, sonuçta, alıntı meydana getirilen bir dizgideki dizideki öğelere genişleme haricinde netice aynı olur. Bu durumda, davranış, “$ *” ve “$ @” dizili dizelerde “$ *” ve “$ @” nin genişletilmesiyle aynıdır: “$ {arr [*]}” tüm öğeleri tek bir sözcük olarak döndürür, oysa “$ {arr [@] } “her maddeyi ayrı bir kelime olarak döndürür.
$ {arr [*]} # Dizideki öğelerin tümü
$ {! arr [*]} # Dizideki tüm dizinler
$ {# arr [*]} # Dizideki unsur sayısı
$ {# arr [0]} # Sıfır öğesinin uzunluğu

Kullanacağınız dizinlerdeki hesaplamaları yukarıdaki benzer biçimde kullandığınızda hesaplamadan çıkıcak sonuçlar size dizin yapısındaki sayıların kaç tane sayı bulunmuş olduğu benzer biçimde bir oldukca fonksiyon ile hesaplama yapmanıza olanak tanır.
Linux üstünde Bash Script Array ağırlıklı olmak suretiyle çeşitli Script yazım teknikleri ile ilgili temel hususların yer almış olduğu makalemizi bitirmiş bulunmaktayız.Öteki makalemizde daha detaylı Scriptler üstünde çalışacağız.Görüşmek suretiyle…