Kabuk Komut Dosyalarındaki İşlevleri Anlama ve Yazma - Bölüm VI


Fonksiyonlar herhangi bir programlama dilinde önemli bir rol oynar. Birçok gerçek programlama dili gibi bash'ın da sınırlı uygulamayla kullanılan işlevleri vardır.

İşlevler nelerdir?

Programlamada işlevler, bir programın belirli bir görevi gerçekleştiren bölümleri olarak adlandırılır. Bu anlamda bir işlev bir tür prosedür veya rutindir. Bir fonksiyon çağrıldığında program kodun geçerli bölümünü terk eder ve fonksiyonun içindeki ilk satırı çalıştırmaya başlar. Tekrarlanan kod olduğunda veya bir görev tekrarlandığında bunun yerine bir işlev kullanmayı düşünün.

Örneğin, belirli bir programın çeşitli aşamalarında bir sayının faktöriyelini bulmamız gereken durumu düşünün. Kodun tamamını (faktöriyeli hesaplamak için) her seferinde yazmak yerine, kodun faktöriyeli hesaplayan kısmını bir bloğun içine bir kez yazabilir ve aynısını birden çok durumda yeniden kullanabiliriz.

Neden fonksiyon yazıyoruz?

  1. Kodu yeniden kullanmamıza yardımcı olur.
  2. Programın okunabilirliğini artırın.
  3. Program içindeki değişkenlerin verimli kullanımı.
  4. Programı parça parça test etmemizi sağlar.
  5. Programı bir dizi alt adım olarak görüntüler.
Kabuk komut dosyalarındaki işlevler

Kabuk komut dosyasında işlevlerin yazılmasına ilişkin genel sözdizimi aşağıdaki yolları içerir.

function func_name {
	. . .
	commands
	. . .
}

or

func_name ( ) {
	. . .
	commands
	. . .
}

Opening curly braces can also be used in the second line as well.

func_name ( )
{
	. . .
	commands
	. . .
}

Normalde kabuk komut dosyalarında yaptığımız gibi, bu fonksiyon bloklarının içine geçerli komutlar yazmakta her zaman özgürsünüz. Şimdi içinde küçük bir fonksiyon bulunan basit bir script yazmaya çalışalım.

#!/bin/bash

call_echo ( ) {
	echo ‘This is inside function’
}

op=$1

if [ $# -ne 1 ]; then
	echo "Usage: $0 <1/0>"
else
	if [ $1 = 0 ] ; then
		echo ‘This is outside function’
	elif [ $1 = 1 ] ; then
		call_echo
	else
		echo ‘Invalid argument’
	fi
fi

exit 0

İşlev tanımı, ona yapılan ilk çağrıdan önce gelmelidir. Çağırmadan önce 'işlevi bildirmek' gibi bir şey yoktur. Ve her zaman fonksiyonları fonksiyonların içine yerleştirebiliriz.

Not:- Boş işlevlerin yazılması her zaman sözdizimi hatalarına neden olur.

Aynı işlev birden çok kez tanımlandığında, çağrılan son sürümdür. Bir örnek alalım.

#!/bin/bash

func_same ( ) {
	echo ‘First definition’
}

func_same ( ) {
	echo ‘Second definition’
}

func_same

exit 0
Parametre alan ve değer döndüren işlevler

Parametre alan ve değer döndüren fonksiyonları ele alarak daha derine inelim. Bir fonksiyondan değer döndürmek için yerleşik 'return' kabuğunu kullanırız. Sözdizimi aşağıdaki gibidir.

func_name ( ) {
	. . .
	commands
	. . .
	return $ret_val
}

Benzer şekilde, aşağıda verildiği gibi boşluklarla ayrılmış işlevlere de argümanlar iletebiliriz.

func_name $arg_1 $arg_2 $arg_3

Fonksiyonun içinde argümanlara $1, $2, $3 vb. sırayla erişebiliriz. Daha fazla netlik sağlamak amacıyla işlevi kullanan maksimum iki tam sayıyı bulmak için aşağıdaki örnek komut dosyasına bakın.

#!/bin/bash

USG_ERR=7

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		echo $1
	else
		echo $2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2
x
if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
	else
		err_str
	fi
else
	err_str
fi

exit 0

Yukarıdakiler biraz karmaşık gibi görünse de satırları okursak basittir. İlk önce doğrulama amacıyla iç içe geçmiş if-else if satırları, yani düzenli ifadelerin yardımıyla bağımsız değişkenlerin sayısını ve türünü kontrol etmek için. Bundan sonra işlevi iki komut satırı argümanıyla çağırırız ve sonucu orada görüntüleriz. Bunun nedeni, bir fonksiyondan büyük tamsayıları döndüremememizdir. Bu soruna geçici bir çözüm bulmanın başka bir yolu da sonucu fonksiyonun içinde saklamak için genel değişkenleri kullanmaktır. Aşağıdaki komut dosyası bu yöntemi açıklamaktadır.

#!/bin/bash

USG_ERR=7
ret_val=

max_two ( ) {
	if [ "$1" -eq "$2" ] ; then
		echo 'Equal'
		exit 0
	elif [ "$1" -gt "$2" ] ; then
		ret_val=$1
	else
		ret_val=$2
	fi
}

err_str ( ) {
	echo "Usage: $0 <number1>  <number2>"
	exit $USG_ERR
}

NUM_1=$1
NUM_2=$2

if [ $# -ne 2 ] ; then
	err_str
elif [ `expr $NUM_1 : '[0-9]*'` -eq ${#NUM_1} ] ; then
	if [ `expr $NUM_2 : '[0-9]*'` -eq ${#NUM_2} ] ; then  
		max_two $NUM_1 $NUM_2
		echo $ret_val
	else
		err_str
	fi
else
	err_str
fi

exit 0

Şimdi, aşağıdaki işlevleri kullanarak önceki kabuk komut dosyası dizisinde açıklanan bazı heyecan verici problemleri deneyin.

  1. Temel Linux Kabuk Komut Dosyası Dili İpuçlarını Anlayın – Bölüm I
  2. Linux'a Yeni Başlayanların Shell Programlamayı Öğrenmesi için 5 Shell Komut Dosyası - Bölüm II
  3. Linux BASH Scripting Dünyasına Yolculuk – Bölüm III
  4. Linux Kabuk Programlamanın Matematiksel Yönü – Bölüm IV
  5. Shell Komut Dosyası Dilinde Matematiksel İfadelerin Hesaplanması – Bölüm V

Bir sonraki bölümde yerel değişkenlerin kullanımı, özyineleme vb. gibi işlevsel özellikler hakkında daha fazla bilgiyle geri döneceğim. Yorumlarla güncel kalın.