Argümanlar

[*] Bu blog içerisinde Python programlama dilinden örnek verdim fakat Python bilmenize gerek yoktur; açıkladım. Eğer bu blog içerisinde bu örneklerden hoşlanmazsanız lütfen Telegram veya Instagram üzerinden bana geribildirim sağlayın.

Bu yazımızda özellikle Bash içerisinde neden bir değişkenin sayı veya özel karakterler ile başlamaması gerektiğini göreceksiniz. Bir önceki blogumuzda read --help şeklinde bir komut verdiğimizi hatırlıyorsunuzdur. Asıl komutun (read) yanına gelen her şey (--hep) aslında bir argümandır. Peki, argümanı tam olarak nasıl anlayabiliriz?

Programlama dünyasında bir adet 'program' vardır ve bir adet 'programı çalıştıran' vardır. Hatırlayın; bu serinin başlarında bir Bash Script'i 'bash <dosyaismi.sh>' şeklinde çalıştırabildiğimizi söylemiştik. Buradaki 'bash', aslında 'programı çalıştıran' rolündedir; '<dosyaismi.sh>' ise 'program'dır, öyle değil mi? Yani biz, '<dosyaismi.sh>' isimli programı, 'bash' yardımıyla çalıştırıyoruz. İşte tam bu noktada 'bash' bir 'programı çalıştıran' iken '<dosyaismi.sh>' bir 'argümandır'. Yani Bash, içerisinde bulunan komutlar sayesinde bir argüman bekler (program) ve onu çalıştırır. Daha sonra './' formatına döndük; programı çalıştıran yine Bash'tir, sadece yöntem değişti.

Başka bir örnek daha vermek istiyorum. Bash ile ilgileniyorsanız yüksek ihtimalle Python kullanmışsınızdır. Python'da bir dosya çalıştırırken genelde 'python '<dosyaismi.py>' şeklinde çalıştırıyorsunuz, öyle değil mi? İşte, buradaki 'python' kelimesi bir 'programı çalıştıran' rolünde iken '<dosyaismi.py>' 'program' yani 'argüman' rolündedir.

Bu durum böyleyken biz, kendi yazdığımız programlara argüman veremez miyiz? Elbette, veririz. İşte bu blog yazısında bunu göreceğiz.

Argümanları belirtirken bir değişken tanımlayıp '$' işaretiyle beraber '1' yazıyoruz. Nasıl olduğunu görelim.

Yukarıda gördüğünüz aslında normal bir değişken tanımlamasıdır ama '$1' sembolü işleri biraz değiştiriyor. İsterseniz kodu çalıştıralım ve ne olacağına birlikte bakalım.

Ne oldu ki? 'Name:' şeklinde bir çıktı aldık; bari '$1' şeklinde bir çıktı alsaydık olmaz mıydı? Dikkat ederseniz 'name' isimli değişkene daha öncekiler gibi 'Cyber Worm' falan yazmadık; $1 yazdık. O zaman bize bir çıktı vermemesi çok normal. Buradaki temel sorun, programı çalıştırma tarzımızdır.

'./practices.ah CyberWorm' mu? Biraz önce söylediklerimi hatırlayın; argümanlar...

Aslında buradaki '$1', CyberWorm gibi bir değerdir; sadece biraz özeldir. Biz bunu bu şekilde tanımladığımız zaman program bizden, programın çalışabilmesi için bir argüman bekler. Blogun ikinci paragrafında './' sembolünün bir 'programı çalıştıran' olduğunu söyledik. Buradaki 'practices.sh' ise 'argümandır'; buraya kadar her şey tamam. Tam bu noktada dolaylı olarak 'practices.sh' dosyası hem bir 'program çalıştıran' sıfatına erişti hem de Bash'in argümanı oldu. Son olarak 'CyberWorm' hem practices.sh için hem de Bash için bir argüman oldu.

Yani 'ana program çalıştırıcı, bash (./)' iken; 'practices.sh' hem Bash'in (./) bir argümanı hem de 'CyberWorm' argümanını alan bir 'program çalıştıran' sıfatındadır. Çünkü içerisindeki kodların çalışabilmesi için 'CyberWorm' argümanına ihtiyacı vardır. Aşağı bıraktığım görsel size bu konu hakkında daha fazla yardımcı olacaktır.

Şimdi, az önce verdiğimiz 'CyberWorm' argümanı 'Mustafa' da olabilirdi; orası bazen size, bazen de programınızın çalışma mantığına göre yani kullanıcıya göre şekillenecektir. Örneğin az önceki örnekte her şey bana bağlıydı ama yazdığınız bir aracı başkası çalıştıracaksa vermesi gereken argümanları bilmelidir. Şimdi, çok önceden yazdığım bir MAC adresi değiştirici programının nasıl çalıştığına bakalım.

Yukarıdaki görselde kırmızı kutu içerisine aldığım kısmı biliyorsunuz; python bir 'ana program çalıştırıcı', macchanger.py ise hem bir program çalıştırıcı hem de bir argümandır. Yeşil kutularda bulunanlar ise (--help gibi) birer argümandır. Yani bu program -i ve -m olmadan çalışmayacaktır. Ben de bunu, 'usage=' yani 'kullanım talimatı' şeklinde bir değişkene atamışım ve kullanıcı yanlış veya eksik bir veri girdiğinde onu uyardığım kodları yazdım. İşte, argümanları kullanırken bu şekilde kullanıcı odaklı olmak zorundasınız.

Çalıştıralım ve bakalım.

Bakın; yukarıda eksiksiz bir çalıştırma işlemi görüyorsunuz ve en altta programın başarılı bir şekilde çalıştığını ifade eden bir yazı var.

Bakın, bu sefer MAC adresi formatını yanlış yazdım ve hata yedim.

Burada bu sefer '-i' argümanını yazmadım ve yine hata aldım.

Burada size anlatmak istediğim şey, argümanların aslında ne kadar inanılmaz yapılar olduğudur. İşte, blogun başında bir argüman tanımlı olduğu hâlde sadece ./practices.sh şeklinde çalıştırdığımızda yalnızca 'Name:' şeklinde bir çıktı almamızın sebebi argümanı vermemiş olmamızdır. Elbette ileride bunları da göreceğiz. Üzerine çok düştüğümün farkındayım ama bunu düzgün anlatan bir insana rastlamadığım için bu kadar detaya girdim.

Şimdi, Bash argümanları üzerinde biraz daha duralım ve konumuzu sonlandıralım.

Yukarıda, biraz önce gördüğünüz name=$1 tanımlamasına benzer tanımlamalar yaptım fakat $ işaretinin yanındaki sayılar farklı. Bunun sebebi; bunların, 'birinci, ikinci, üçüncü ve dördüncü argümanlar' olmasından kaynaklıdır. Argümanların sırasını ve sayısını bu şekilde ayarlayabiliyoruz. Çalıştırınca ne olacağını tahmin ediyorsunuzdur ancak yine de çalıştırıp ne olduğuna bakalım.

Evet, yine echo ile normal bir yazı yazdık ve değişkenleri olması gerektikleri yerlere serpiştirdik; çıktımız şaşırtıcı olmadı.

Şimdi, ilk bakışta çok işe yaramayan ama mantığı anladıktan sonra işe yarayabileceğini düşüneceğiniz bir kullanım sağlayacağız: '$#'

En alt satırda gördüğünüz 'echo $#' komutu bize, terminalde gördüğünüz '4' sonucunu verdi. Bu, program içerisinde kaç adet argüman olduğunu görmemize olanak tanır. İsterseniz bu kodu biraz da iyileştirebiliriz:

Çıktımız daha güzel bir hâl aldı. Peki, bu bizim ne işimize yarayacak? Tahmin edebileceğiniz üzere oradaki 'echo' komutunu, sayıyı çıktıda görebilmemiz için yazdım. Peki, "eğer argümanlar olması gerekenden az veya çoksa kullanıcıyı uyar" algoritmalı bir kod yazsak sizce de kod üzerindeki hakimiyetimiz artmayacak mıdır? Elbette artacaktır. İşte, bu komutu bu yüzden kullanıyoruz.

Yukarıdaki kodu anlamanıza gerek yoktur çünkü henüz işlemediğimiz bir konuyla alakalıdır ama kırmızı kutu içerisindeki alan şunu ifade ediyor: "Eğer argümanlar ($#) 4'e eşitse (yani olması gereken sayıdaysa) argümanları yazdır. Eğer argümanlar ($#) 4'e eşit değilse (yani olması gereken sayıda değilse) 'Wrong args.' yazdır."

Numaraların olduğu kısma bakalım şimdi. 1 numaralı kısımda argümanları tam ve doğru biçimde yazdık yani 4 adet argümanımız var. Dolayısıyla Bash'e söylediğimiz gibi argümanları yazdırdı.

2 numaralı kısımda ise olmayanbirarguman şeklinde bir argüman daha eklemişim ve karşılaştığım sonuç yine Bash'e dediğimiz gibi 'Wrong args.'

3 numaralı kısımda da bu sefer bir argümanı eksik yazdık (Security). Bu koşulda argümanlar yine 4'e eşit olmadığı için 'Wrong args.' yazısını görüyoruz.

İşte, kullanıcı programı çalıştırma konusunda bir hata yaptığında ona bu şekilde (elbette daha açıklayıcı) açıklamalar yapabiliriz. '$#' komutunun ne kadar önemli olduğunu anlamış olduk.

Son olarak başka bir komutu daha görelim ve bitirelim: 'args=("$@")'

Bu komutu verdiğimiz zaman Bash, verdiğimiz tüm argümanları bir diziye (array) ekliyor; bir önceki blogda mantığını anlattım. Buradaki 'args', 'echo' gibi özel bir anahtar kelimedir ve o olmadan bu işi yapamazsınız. Dizilerde 'index' mantığı vardı. Bu mantıkta sıfırıncı index, aslında dizinin birinci elemanını temsil ediyordu. İşte, argümanlar arasından çekmek (görüntülemek) istediğiniz herhangi bir argüman varsa bunu kullanmanız gerekir. Ne demek istiyorum?

Kırmızı kutucuktaki gibi kullanıyoruz. Hemen altındaki kısma baktığınızda da '${args[0]}' şeklinde ifadelerin yer aldığını görürsünüz. Eğer ne olduğunu bilmiyorsanız lütfen bir önceki blogu da okuyun. Biz burada, argümanların her birini tek tek çağırmış ve 'echo' ile yazdırmış olduk. İşte, argümanların dizi şeklinde kontrol altına alınması da bu şekilde oluyor.


Yayınlanma Tarihi: 2022-09-03 23:46:25

Son Düzenleme Tarihi: 2022-09-08 15:35:02