0Pricing
Linux Command Line & Bash Scripting Mastery · Ders

Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama

Kırılgan genel değişkenler yerine yerel değişkenler, çıkış durumları ve printf tabanlı dönüş değerleri kullanan işlevler yazın.

Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama, CoddyKit'te ücretsiz bir Linux Command Line & Bash Scripting Mastery dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Linux Command Line & Bash Scripting Mastery öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Linux Command Line & Bash Scripting Mastery kursu toplamda 4 dersten oluşur.

İşlev Kapsamı Neden Önemlidir?

Bash'te değişkenler varsayılan olarak geneldir. Bir işlevin içinde ayarlanan değişkeni açıkça local olarak bildirmediğiniz sürece bu değişken çağıranın kapsamına sızar. Bu, kabuk betiklerindeki ince hataların yaygın bir kaynağıdır.

  • local kullanılmayan işlevler, çağıranın değişkenlerinin üzerine sessizce yazabilir.
  • local değişkenleri, işlev döndüğünde yok edilir.
  • Temiz kapsam sınırları, işlevleri yalıtılmış biçimde yeniden kullanılabilir ve sınanabilir hâle getirir.

Bu ders, kendi içinde bağımsız işlevler yazmayı öğretir: Bu işlevler local değişkenleri kullanır, sonuçları çıkış kodları ve printf aracılığıyla iletir ve örtük genel duruma asla güvenmez.

Global Değişken Sızıntısı Sorunu

Burada global bir değişken sızıntısına ilişkin somut bir örnek verilmiştir. set_name işlevi result adlı bir değişken tanımlar ve bu değişken, çağıranın kendi result değişkeninin üzerine sessizce yazılır.

Bu betiği çalıştırıp beklenmedik çıktıyı gözlemleyin — işlev çağrısından sonra çağıranın result değişkeni ortadan kaybolur.

#!/usr/bin/env bash

set_name() {
    result="Alice"   # No 'local' — this is GLOBAL
}

result="important data"
echo "Before: $result"

set_name

echo "After:  $result"   # Prints 'Alice', not 'important data'

'local' ile Yerel Değişken Tanımlama

local yerleşik komutu, bir değişkenin kapsamını onu çevreleyen işleve ve bu işlevin çağırdığı tüm işlevlere sınırlar. İşlevin dışında değişken ya tanımsız olur ya da önceki değerini korur.

  • local varname — değer atamadan tanımlar.
  • local varname="value" — tek adımda tanımlar ve değer atar.
  • local -i count=0 — tamsayı türünde bir yerel değişken tanımlar.
  • local -r PI=3.14159 — salt okunur bir yerel sabit tanımlar.

En iyi uygulama: Global olması özellikle gerekmiyorsa, bir işlevin içindeki her değişkeni local olarak tanımlayın.

#!/usr/bin/env bash

greet() {
    local name="$1"          # local — safe
    local greeting="Hello, ${name}!"
    echo "$greeting"
}  # 'name' and 'greeting' vanish here

name="global value"
greet "Bob"
echo "name is still: $name"   # Prints 'global value'

Dönüş Değerleri Olarak Çıkış Kodları

Bash işlevleri dizeleri return ile döndüremez — return yalnızca bir tamsayı çıkış durumu (0–255) belirler. Geleneksel olarak:

  • return 0 — başarı
  • return 1 (veya sıfır olmayan herhangi bir değer) — başarısızlık

Çağıran, çağrıdan hemen sonra $? üzerinden çıkış durumunu okur veya işlevi doğrudan bir if koşulunda kullanır. Çıkış kodları, bir işlevden başarıyı veya başarısızlığı bildirmek için tercih edilen yöntemdir.

#!/usr/bin/env bash

is_even() {
    local -i n="$1"
    (( n % 2 == 0 ))   # arithmetic command: exits 0 if true, 1 if false
}

for num in 2 3 7 10; do
    if is_even "$num"; then
        echo "$num is even"
    else
        echo "$num is odd"
    fi
done

printf ile Dize Sonuçlarını İletme

Bir işlevin dize sonucu döndürmesi gerektiğinde kullanılan standart yöntem, standart çıktıya yazdırmak ve sonucu komut ikamesi $() ile yakalamaktır. echo yerine printf kullanılması şu nedenlerle tercih edilir:

  • printf, siz eklemediğiniz sürece varsayılan olarak sona satır sonu eklemez (ancak \n eklerseniz ekler).
  • printf davranışı tutarlıdır ve POSIX tarafından tanımlanmıştır; echo kabuklar arasında farklılık gösterir.
  • Komut ikamesi sondaki satır sonlarını kaldırır; bu nedenle printf '%s' "$value" kesin sonuç verir.
#!/usr/bin/env bash

to_uppercase() {
    local input="$1"
    printf '%s' "${input^^}"   # Bash 4+ parameter expansion
}

word="hello"
upper=$(to_uppercase "$word")
echo "Original: $word"
echo "Upper:    $upper"

Çıkış Kodlarını ve Standart Çıktıyı Birleştirme

İyi tasarlanmış bir işlev aynı anda hem bir sonuç yazdırabilir (başarılı olduğunda) hem de başarısızlığı bildirebilir (çıkış kodu aracılığıyla). Çağıran, çıktıya güvenmeden önce çıkış koduna göre ne yapacağına karar verir.

Aşağıdaki yöntem gerçek Bash kitaplıklarında yaygın olarak kullanılır:

  • Başarı durumunda: sonucu printf ile yazdırın ve return 0 kullanın.
  • Başarısızlık durumunda: tanı iletisini standart hataya (standart çıktıya değil) yazın ve return 1 kullanın.
  • Hataları standart hataya yazmak, standart çıktıyı ardışık işleme için temiz tutar.
#!/usr/bin/env bash

divide() {
    local -i numerator="$1"
    local -i denominator="$2"

    if (( denominator == 0 )); then
        printf 'Error: division by zero\n' >&2
        return 1
    fi

    printf '%d' $(( numerator / denominator ))
    return 0
}

if result=$(divide 20 4); then
    echo "20 / 4 = $result"
else
    echo "Division failed."
fi

if result=$(divide 10 0); then
    echo "10 / 0 = $result"
else
    echo "Division failed (caught the error)."
fi

'local' Kullanarak Özyinelemeli İşlevleri Korumak

Özyineleme, local komutunun neden vazgeçilmez olduğunu en açık biçimde gösteren örneklerden biridir. Her özyinelemeli çağrı, çağrı yığınındaki her local değişkenin kendisine ait bağımsız bir kopyasını alır. local kullanılmazsa her çağrı aynı global değişkenin üzerine yazacak ve yanlış sonuçlar üretecektir.

Aşağıdaki faktöriyel işlevi güvenlidir; çünkü n ve sub her yığın çerçevesi için yereldir.

#!/usr/bin/env bash

factorial() {
    local -i n="$1"
    local -i sub

    if (( n <= 1 )); then
        printf '1'
        return 0
    fi

    sub=$(factorial $(( n - 1 )))
    printf '%d' $(( n * sub ))
}

for i in 1 2 3 4 5 6; do
    echo "${i}! = $(factorial $i)"
done

local -n (İsim Başvurusu) ile Alt Kabuk Tuzaklarından Kaçınma

Komut ikamesi $() bir alt kabukta çalışır. İçindeki değişken atamaları üst kabukta görünmez. Bir işlevin, alt kabuk kullanmadan çağıran tarafından sağlanan bir değişkene yazmasını istediğinizde Bash 4.3 ve sonraki sürümlerde kullanılabilen bir isim başvurusu (local -n) kullanın.

  • local -n ref="$1", ref değişkenini $1 içinde adı saklanan değişkenin takma adı yapar.
  • İşlev içinde ref değişkenine değer atamak, çağıranın değişkenini doğrudan değiştirir.
  • Bu yöntem, uygulama ayrıntılarını yerel tutarken alt kabuk kullanımını önler.
#!/usr/bin/env bash

# Fills caller's array by reference — no subshell needed
read_csv_line() {
    local -n _out="$1"    # nameref to caller's variable
    local line="$2"
    local IFS=','
    read -ra _out <<< "$line"
}

declare -a fields
read_csv_line fields "alice,30,engineer"

echo "Name:  ${fields[0]}"
echo "Age:   ${fields[1]}"
echo "Role:  ${fields[2]}"

Küçük Bir İşlev Kitaplığı Oluşturma

Gerçek dünyadaki Bash projeleri, yeniden kullanılabilir işlevleri source ile (veya nokta işleci . ile) betiklere aktarılan kitaplık dosyalarına ayırır. İyi kitaplık tasarımı kuralları şunlardır:

  • Bir kitaplık işlevinin içindeki her değişken local olmalıdır.
  • Kitaplık işlevleri hiçbir zaman exit kullanmaz — çağıranın çalışmaya devam edebilmesi için return kullanırlar.
  • Ad çakışmalarını önlemek için tutarlı bir ad alanı ön eki kullanın (ör. str_, log_).
  • Bir koruyucu değişken kullanarak dosyanın birden fazla kez aktarılmasını önleyin.

Aşağıda bu kuralları izleyen minimal bir dize yardımcı programı kitaplığı yer almaktadır.

#!/usr/bin/env bash
# lib/str.sh  — string utility library

[[ -n "${_LIB_STR_LOADED:-}" ]] && return 0
_LIB_STR_LOADED=1

str_trim() {
    local str="$1"
    str="${str#"${str%%[![:space:]]*}"}"
    str="${str%"${str##*[![:space:]]}"}" 
    printf '%s' "$str"
}

str_repeat() {
    local -i times="$2"
    local char="$1"
    local -i i
    for (( i = 0; i < times; i++ )); do
        printf '%s' "$char"
    done
}

str_contains() {
    local haystack="$1"
    local needle="$2"
    [[ "$haystack" == *"$needle"* ]]
}

# --- self-test when executed directly ---
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
    trimmed=$(str_trim "   hello world   ")
    echo "Trimmed: '${trimmed}'"
    str_repeat '-' 20; echo
    if str_contains "bash scripting" "script"; then
        echo "Contains: yes"
    fi
fi

İşlevlerin İçindeki Bağımsız Değişkenleri Doğrulama

Bağımsız değişken alan işlevler, bunları erkenden doğrulamalı ve geçersiz girdi durumunda belirli bir çıkış kodu döndürmelidir. Buna koruyucu koşul yöntemi denir — hızlı ve açık biçimde başarısız olun.

  • Bağımsız değişken sayısını $# ile denetleyin.
  • Herhangi bir işlem yapmadan önce türleri veya biçimleri doğrulayın.
  • Tanı iletilerini yalnızca standart hataya yazdırın; standart çıktıya asla yazdırmayın.
  • Farklı başarısızlık türlerine farklı tepki verebilmeleri için birbirinden farklı sıfır olmayan dönüş kodları kullanın (ör. 1 = yanlış bağımsız değişkenler, 2 = dosya bulunamadı).
#!/usr/bin/env bash

file_line_count() {
    if (( $# != 1 )); then
        printf 'Usage: file_line_count <file>\n' >&2
        return 1
    fi

    local file="$1"

    if [[ ! -f "$file" ]]; then
        printf 'Error: not a file: %s\n' "$file" >&2
        return 2
    fi

    if [[ ! -r "$file" ]]; then
        printf 'Error: cannot read: %s\n' "$file" >&2
        return 3
    fi

    local -i count
    count=$(wc -l < "$file")
    printf '%d' "$count"
    return 0
}

# Test with /etc/hosts (exists on every Linux/macOS system)
if lines=$(file_line_count /etc/hosts); then
    echo "/etc/hosts has $lines lines"
else
    echo "Failed with exit code: $?"
fi

Hepsini Bir Araya Getirme: Gerçek Dünya Örneği

Bu dersteki tüm kavramların birlikte çalışmasını gösteren, eksiksiz ve kendi içinde bağımsız bir betik aşağıda verilmiştir:

  • Her işlevde local değişkenler.
  • Başarıyı veya başarısızlığı bildirmek için çıkış kodları.
  • Dize sonuçlarını iletmek için printf.
  • Standart hataya yazılan hatalar, standart çıktıya yazılan sonuçlar.
  • Bağımsız değişken doğrulama için koruyucu koşullar.

Akışı inceleyin: parse_version verileri çıkarır, version_ge bunları karşılaştırır ve main her ikisini de düzenli biçimde kullanır.

#!/usr/bin/env bash

# Parse a semver string into components via nameref
parse_version() {
    local -n _major="$2" _minor="$3" _patch="$4"
    local version="$1"
    local IFS='.'
    local -a parts
    read -ra parts <<< "$version"
    _major="${parts[0]:-0}"
    _minor="${parts[1]:-0}"
    _patch="${parts[2]:-0}"
}

# Return 0 if version $1 >= version $2
version_ge() {
    local -i maj_a min_a pat_a
    local -i maj_b min_b pat_b
    parse_version "$1" maj_a min_a pat_a
    parse_version "$2" maj_b min_b pat_b

    if   (( maj_a != maj_b )); then (( maj_a > maj_b ))
    elif (( min_a != min_b )); then (( min_a > min_b ))
    else                             (( pat_a >= pat_b ))
    fi
}

require_bash_version() {
    local required="$1"
    local actual="${BASH_VERSION%%(*}"
    if version_ge "$actual" "$required"; then
        printf 'Bash %s satisfies >= %s\n' "$actual" "$required"
        return 0
    else
        printf 'Error: need Bash >= %s, got %s\n' "$required" "$actual" >&2
        return 1
    fi
}

main() {
    require_bash_version "4.3" || return 1
    require_bash_version "99.0" || true   # demonstrates failure path
}

main

Bilginizi Sınayın: Yerel Değişkenler ve Dönüş Değerleri

Aşağıdaki Bash işlevini inceleyin. Çağıran içinde dize sonucunu yakalamanın doğru yolu nedir ve tmp değişkeniyle ilgili hangi ifade doğrudur?

transform() {
    local tmp="${1,,}"   # lowercase
    printf '%s' "$tmp"
    return 0
}

Özet: Yerel Kapsamlı ve Dönüş Kodlu İşlevler

Bu derste temiz, birleştirilebilir ve güvenli Bash işlevlerinin nasıl yazılacağını öğrendiniz:

  • İşlevlerin içindeki değişkenler için her zaman local kullanın; böylece çağıranın kapsamını kirletmezsiniz.
  • Başarıyı veya başarısızlığı bildirmek için çıkış kodlarını (return 0/1/N) kullanın — bunlar if, && ve || ile doğal biçimde bütünleşir.
  • Dize sonuçlarını iletmek için standart çıktıya printf ile yazın; çağıran içinde bunları $() ile yakalayın.
  • Hataları standart hataya (>&2) yazın; böylece veri akışı ve ardışık işleme için standart çıktı temiz kalır.
  • Çağıranın sağladığı bir değişkene alt kabuk ek yükü olmadan yazmanız gerektiğinde local -n (isim başvurusu) kullanın.
  • Koruyucu koşullar (bağımsız değişkenleri erkenden doğrulamak, geçersiz girdide hemen dönmek) işlevleri sağlam ve kendi kendini açıklayan hâle getirir.
  • Kitaplık dosyaları aktarılmalı, ad alanı ön ekleri kullanmalı, hiçbir zaman exit çağırmamalı ve birden fazla kez aktarılmaya karşı korunmalıdır.

Bu yöntemlerde ustalaşmak, kırılgan ve tek kullanımlık betiklerle profesyonel, sürdürülebilir Bash kod tabanları arasındaki farkı oluşturur.

Sıkça Sorulan Sorular

“Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama” dersi ücretsiz mi?

Evet — “Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Linux Command Line & Bash Scripting Mastery kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Linux Command Line & Bash Scripting Mastery kursu toplamda 4 dersten oluşur.

“Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama” dersinde ne öğreneceğim?

Kırılgan genel değişkenler yerine yerel değişkenler, çıkış durumları ve printf tabanlı dönüş değerleri kullanan işlevler yazın. Linux Command Line & Bash Scripting Mastery ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Linux Command Line & Bash Scripting Mastery öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Linux Command Line & Bash Scripting Mastery, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.

“Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Linux Command Line & Bash Scripting Mastery dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Linux Command Line & Bash Scripting Mastery dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Yerel Kapsam ve Dönüş Kodlarıyla İşlev Tasarlama
  2. Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma
  3. getopts ile Bayrakları ve Bağımsız Değişkenleri Ayrıştırma
  4. Dizileri ve İlişkilendirilebilir Haritaları İşlevler Arasında Geçirme
← Linux Command Line & Bash Scripting Mastery Sayfasına Dön