0Pricing
Linux Command Line & Bash Scripting Mastery · Ders

Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma

Paylaşılan yardımcıları include korumaları ve ad alanlı işlev ön ekleri içeren, kaynaktan alınabilir .sh kitaplık dosyalarında düzenleyin.

Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma, CoddyKit'te ücretsiz bir Linux Command Line & Bash Scripting Mastery dersidir. Bu, 4 dersinin 2. 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.

Bash Kitaplığı Nedir?

Yazılım mühendisliğinde kitaplık, birden fazla programın paylaşabildiği yeniden kullanılabilir işlevler koleksiyonudur. Bash, aynı kavramı aktarılabilir kabuk betikleri aracılığıyla destekler.

Yardımcı işlevleri her betiğe kopyalayıp yapıştırmak yerine, bunları özel bir .sh dosyasına yerleştirip source komutuyla (veya kısa biçimi olan . ile) yükleyebilirsiniz. Bu dosyada tanımlanan tüm işlevler, değişkenler ve takma adlar, çağıran betiğin mevcut kabuk oturumunda kullanılabilir hâle gelir.

  • DRY ilkesini (Kendinizi Tekrarlamayın) destekler
  • Hata düzeltmelerini merkezîleştirir — bir kez düzeltildiğinde tüm çağıranlar yararlanır
  • Tek tek betikleri kısaltır ve okunmalarını kolaylaştırır
  • Günlük kaydı, hata işleme ve yardımcı mantıkta ekip genelinde tutarlılık sağlar

İyi yapılandırılmış bir Bash projesinde, üst düzey dillerin kurallarını yansıtan ve bu ortak dosyaları içeren bir lib/ dizini bulunur.

source Komutu ve Nokta İşleci

Bir kitaplık dosyasını mevcut kabuk ortamına yüklemenin eşdeğer iki yolu vardır:

  • source /path/to/lib.sh — açık ve okunabilir biçim
  • . /path/to/lib.sh — POSIX uyumlu kısa biçim

Her ikisi de dosyayı bir alt kabukta değil, mevcut kabuk işlemi içinde çalıştırır; bu nedenle dosyada tanımlanan her işlev ve değişken, çağrıdan hemen sonra betiğinizin ortamının parçası olur.

Yaygın bir yöntem, kitaplığı çağıran betiğe göre konumlandırmak için $BASH_SOURCE kullanmaktır. Böylece proje nereye kurulmuş olursa olsun taşınabilirliğini korur.

#!/usr/bin/env bash
# main.sh — load a library relative to this script's own location

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/lib/utils.sh"

echo "Library loaded. Calling greet..."
greet "World"

İlk Kitaplık Dosyanızı Oluşturma

Kitaplık dosyası yalnızca işlev tanımlarını (ve bazen sabitleri) içeren düz bir .sh dosyasıdır. Üst düzeyde yan etki oluşturan hiçbir kodu çalıştırmamalıdır — doğrudan çalıştırılmak için değil, aktarılmak için tasarlanmıştır.

Temel kurallar:

  • Kitaplığın amacını açıklayan bir shebang yorumu ile başlayın
  • Yalnızca işlevleri tanımlayın — üst düzeyde main mantığı bulunmasın
  • İşlevlerin içinde return kullanın (çağıranı sonlandıracak exit komutunu asla kullanmayın)
  • Dosyayı projenizin lib/ alt dizininde tutun
#!/usr/bin/env bash
# lib/utils.sh — General-purpose utility functions

# Print a greeting message
greet() {
    local name="${1:-stranger}"
    echo "Hello, ${name}!"
}

# Print a timestamped log line to stderr
log_info() {
    echo "[INFO]  $(date '+%Y-%m-%d %H:%M:%S')  $*" >&2
}

# Print an error message and return a failure code
log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S')  $*" >&2
    return 1
}

Dahil Etme Koruyucuları: Birden Fazla Aktarımı Önleme

Birkaç betik aynı kitaplığı aktardığında veya bir kitaplık ana betik tarafından da aktarılan başka bir kitaplığı aktardığında, işlevler birden fazla kez tanımlanabilir. Bu durum zaman kaybına yol açar ve bir işlevin gövdesi çalışma sırasında değiştirilirse fark edilmesi zor hatalara neden olabilir.

Çözüm, bir bayrak görevi gören bir değişken olan dahil etme koruyucusudur. İlk yüklemede değişken tanımsızdır ve dosya çalışmaya devam eder. Sonraki her yüklemede koruyucu zaten ayarlanmış olduğundan dosya hemen geri döner.

Bu, Bash'te C/C++ içindeki #pragma once veya diğer dillerdeki if not already imported yöntemlerinin karşılığıdır.

#!/usr/bin/env bash
# lib/utils.sh — with include guard

# Guard: if already sourced, do nothing
[[ -n "${_LIB_UTILS_LOADED:-}" ]] && return 0
_LIB_UTILS_LOADED=1

greet() {
    local name="${1:-stranger}"
    echo "Hello, ${name}!"
}

log_info() {
    echo "[INFO]  $(date '+%Y-%m-%d %H:%M:%S')  $*" >&2
}

log_error() {
    echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S')  $*" >&2
    return 1
}

Ad Alanlı İşlev Ön Ekleri

Bash, işlevler için tek bir global ad alanına sahiptir. İki kitaplık da log veya init adlı bir işlev tanımlarsa ikinci tanım, ilkinin üzerine sessizce yazılır.

Standart çözüm bir ad alanı ön eki kullanmaktır: Bir kitaplıktaki her işlevin önüne, kitaplığın kısa adı ve ardından iki iki nokta (::) veya bir alt çizgi getirilir. Örneğin dize yardımcı programları kitaplığında str::, dosya kitaplığında ise file:: kullanılır.

  • Çakışma olasılığı son derece azalır
  • Çağıran kod kendi kendini açıklar — str::trim, işlevin tam olarak nerede bulunduğunu gösterir
  • Grep ile bulunabilirlik artar: grep 'str::' main.sh tüm dize kitaplığı çağrılarını anında gösterir
#!/usr/bin/env bash
# lib/str.sh — String utility library (namespaced)

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

# Trim leading and trailing whitespace
str::trim() {
    local s="$1"
    s="${s#"${s%%[![:space:]]*}"}"
    s="${s%"${s##*[![:space:]]}"}"  
    echo "$s"
}

# Convert string to uppercase
str::upper() {
    echo "${1^^}"
}

# Convert string to lowercase
str::lower() {
    echo "${1,,}"
}

# Check if a string contains a substring
str::contains() {
    [[ "$1" == *"$2"* ]]
}

lib/ Dizininizi Düzenleme

Proje büyüdükçe tek bir utils.sh dosyasını yönetmek zorlaşır. Sorumlulukları lib/ dizinindeki amaca odaklanmış kitaplık dosyalarına ayırın:

  • lib/log.sh — günlük kaydı yardımcıları (log::info, log::warn, log::error)
  • lib/str.sh — dize işlemleri (str::trim, str::upper)
  • lib/fs.sh — dosya sistemi yardımcıları (fs::require_dir, fs::safe_rm)
  • lib/net.sh — ağ denetimleri (net::wait_for_port, net::is_online)

Tek bir önyükleme yükleyicisi dosyası (lib/bootstrap.sh), bunların tümünü doğru sırayla aktarabilir; böylece her betiğin yalnızca bir aktarım çağrısı yapması yeterli olur.

#!/usr/bin/env bash
# lib/bootstrap.sh — Load all project libraries in dependency order

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

_BOOTSTRAP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

source "${_BOOTSTRAP_DIR}/log.sh"
source "${_BOOTSTRAP_DIR}/str.sh"
source "${_BOOTSTRAP_DIR}/fs.sh"
source "${_BOOTSTRAP_DIR}/net.sh"

log::info "All libraries loaded."

Eksiksiz Bir Günlük Kaydı Kitaplığı

Günlük kaydı, betikler arasında en sık paylaşılan sorumluluktur. Özel bir lib/log.sh kitaplığı, çıktı biçimlendirmesini, günlük düzeylerini ve renk kodlarını merkezileştirir.

Böyle bir kitaplık kullanıldığında, projedeki her betik biçimlendirme kodunu yinelemeden tutarlı, zaman damgalı ve renk kodlu iletiler yazdırır.

#!/usr/bin/env bash
# lib/log.sh — Coloured, levelled logging library

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

# Colour codes (disabled when not writing to a terminal)
_LOG_RED=''; _LOG_YEL=''; _LOG_GRN=''; _LOG_RST=''
if [[ -t 2 ]]; then
    _LOG_RED='\033[0;31m'
    _LOG_YEL='\033[0;33m'
    _LOG_GRN='\033[0;32m'
    _LOG_RST='\033[0m'
fi

_log::_print() {
    local level="$1" colour="$2"; shift 2
    printf "%b[%s]%b %s  %s\n" \
        "$colour" "$level" "$_LOG_RST" \
        "$(date '+%H:%M:%S')" "$*" >&2
}

log::info()  { _log::_print 'INFO ' "$_LOG_GRN" "$@"; }
log::warn()  { _log::_print 'WARN ' "$_LOG_YEL" "$@"; }
log::error() { _log::_print 'ERROR' "$_LOG_RED" "$@"; return 1; }
log::fatal() { _log::_print 'FATAL' "$_LOG_RED" "$@"; exit 1; }

Bir Dosya Sistemi Yardımcıları Kitaplığı

Dosyaları ve dizinleri değiştiren betikler genellikle aynı savunmacı denetimleri tekrarlar: Bu dizin var mı? Bu yol yazılabilir mi? Önemli bir şeyi silmek üzere miyim?

Bu denetimleri lib/fs.sh içinde merkezileştirmek, bu betikleri hem daha güvenli hem de daha okunabilir hâle getirir. Her işlevin başarısızlık durumunda exit yerine return 1 kullandığına dikkat edin; bu, çağıranın hatayı uygun biçimde ele alabilmesini sağlar.

#!/usr/bin/env bash
# lib/fs.sh — Filesystem helper library

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

# Ensure a directory exists; create it if not
fs::require_dir() {
    local dir="$1"
    if [[ ! -d "$dir" ]]; then
        mkdir -p "$dir" || { echo "[fs] Cannot create directory: $dir" >&2; return 1; }
    fi
}

# Remove a file only if it exists (no error on missing)
fs::safe_rm() {
    local target="$1"
    [[ -e "$target" ]] && rm -rf -- "$target"
    return 0
}

# Assert that a file exists and is readable
fs::require_file() {
    local file="$1"
    [[ -f "$file" && -r "$file" ]] || {
        echo "[fs] Required file missing or unreadable: $file" >&2
        return 1
    }
}

Kitaplığınızı Bir Sabitle Sürümlemek

Kitaplıklarınız birden çok proje arasında paylaşıldığında veya bir ekibe dağıtıldığında, çalışma zamanında hangi sürümün yüklendiğini bilmek önem kazanır. Basit bir yaklaşım, her kitaplıktan bir sürüm sabiti dışa aktarmaktır.

Ardından çağıranlar başlangıçta en düşük sürüm koşulunu doğrulayabilir ve anlaşmazlıkları daha sonra gizemli başarısızlıkların kök nedenini araştırmak yerine erkenden yakalayabilir. Koruma değişkeni sürüm dizesi olarak da kullanılır; böylece tek bir değişken iki sorumluluğu birleştirir.

#!/usr/bin/env bash
# lib/str.sh — versioned example

# Guard doubles as the version identifier
[[ -n "${_LIB_STR_LOADED:-}" ]] && return 0
readonly _LIB_STR_LOADED='1.3.0'

# Caller can validate the version
str::version() { echo "$_LIB_STR_LOADED"; }

# ---- Utility functions ----
str::trim() {
    local s="$1"
    s="${s#"${s%%[![:space:]]*}"}"
    s="${s%"${s##*[![:space:]]}"}"  
    echo "$s"
}

str::repeat() {
    local str="$1" count="$2" result=''
    for (( i=0; i<count; i++ )); do result+="$str"; done
    echo "$result"
}

Kendi İçinde Tam Bir Tanıtım: Birden Çok Kitaplık Kullanma

Bu sahnede iki kitaplığı kaynak olarak yükleyen ve her birindeki işlevleri kullanan gerçekçi bir betik gösterilmektedir. Ana betiğin nasıl temiz kaldığına dikkat edin: amacı ifade ederken tüm uygulama ayrıntıları kitaplıklarda bulunur.

Kitaplıkları geçici dosyalara yazılan here-belgeleri kullanarak satır içinde tanımladığı için betik bağımsız bir dosya olarak çalıştırılabilir. Gerçek bir projede her kitaplık lib/ altında kendine ait bir dosyada bulunurdu.

#!/usr/bin/env bash
# Standalone demo: inline libs written to /tmp, then sourced
set -euo pipefail

# --- Create a temporary lib/log.sh ---
TMPDIR_LIBS="$(mktemp -d)"
trap 'rm -rf "$TMPDIR_LIBS"' EXIT

cat > "${TMPDIR_LIBS}/log.sh" <<'LIBEOF'
[[ -n "${_LIB_LOG_LOADED:-}" ]] && return 0
_LIB_LOG_LOADED=1
log::info()  { echo "[INFO]  $*"; }
log::error() { echo "[ERROR] $*" >&2; return 1; }
LIBEOF

cat > "${TMPDIR_LIBS}/str.sh" <<'LIBEOF'
[[ -n "${_LIB_STR_LOADED:-}" ]] && return 0
_LIB_STR_LOADED=1
str::upper() { echo "${1^^}"; }
str::trim()  { local s="$1"; s="${s#"${s%%[![:space:]]*}"}";
               s="${s%"${s##*[![:space:]]}"}"  ; echo "$s"; }
LIBEOF

# --- Source both libraries ---
source "${TMPDIR_LIBS}/log.sh"
source "${TMPDIR_LIBS}/str.sh"

# --- Main logic ---
log::info "Libraries loaded successfully."
raw_input="   hello from bash libraries   "
trimmed="$(str::trim "$raw_input")"
log::info "Trimmed: '${trimmed}'"
log::info "Uppercased: '$(str::upper "$trimmed")'"

En İyi Uygulamalar ve Yaygın Hatalar

Bir kitaplığı ekip kullanımı için yayımlamadan önce şu kontrol listesini uygulayın:

  • Dahil etme koruması — her kitaplıkta bir tane bulunmalıdır; koruma değişkeninin adını en üstte belgeleyin
  • Üst düzey yan etkiler olmamalı — bir işlev gövdesinin dışında hiçbir zaman cd veya echo çalıştırmayın ve genel durumu değiştirmeyin
  • İşlevlerin içindeki tüm değişkenler için local kullanın — local kullanılmadığında her atama çağıranın kapsamına sızar
  • Geri döndürün, hiçbir zaman çıkmayın — kaynak olarak yüklenen bir dosyanın içindeki exit, çağıran kabuğun tamamını sonlandırır
  • Girdileri doğrulayın — gerekli bağımsız değişkenleri denetleyin ve eksik olduklarında anlamlı bir hata kodu döndürün
  • Açıklamalarla belgeleyin — her işlevin ne yaptığını, parametrelerini ve dönüş değerini açıklayın
  • Kitaplık dosyalarının içinde set -e kullanmaktan kaçının — çağıranların kendi hata işleme stratejileri olabilir; kararı onlara bırakın

Bilgi Kontrolü: Dahil Etme Korumaları

main.sh dosyasının hem lib/bootstrap.sh hem de lib/log.sh dosyasını kaynak olarak yüklediği, lib/bootstrap.sh dosyasının da kendi içinde lib/log.sh dosyasını kaynak olarak yüklediği bir proje düşünün. lib/log.sh içindeki dahil etme korumasının temel amacı nedir?

Ders Özeti: Bash Kitaplıklarını Doğru Kullanma

Yeniden kullanılabilir Bash kitaplıkları oluşturmak ve kullanmak için gereken tüm temel teknikleri ele aldınız. Akılda tutmanız gerekenler şunlardır:

  • source veya . ile kaynak olarak yükleyin — bir dosyayı mevcut kabuğa yükler ve işlevlerini hemen kullanılabilir hâle getirir
  • Kitaplık yollarını çağıran betiğe göre çözümlemek ve projeleri taşınabilir tutmak için $BASH_SOURCE kullanın
  • Dahil etme korumaları ([[ -n "${_GUARD:-}" ]] && return 0), birden çok dosya aynı kitaplığı kaynak olarak yüklediğinde yinelenen tanımları önler
  • Ad alanı ön ekleri (log::, str::, fs::), kitaplıklar arasındaki işlev adı çakışmalarını ortadan kaldırır
  • Odaklanmış ve tek sorumluluklu dosyalardan oluşan bir lib/ dizini, büyük projelerin bakımını kolaylaştırır
  • Bir başlangıç yükleyicisi (lib/bootstrap.sh), tüm ekosistemi yüklemek için her betiğe tek bir kaynak yükleme çağrısı sağlar
  • Kitaplık dosyalarında hiçbir zaman exit veya üst düzey yan etkiler kullanmayın — burada yalnızca işlev tanımları ve sabitler bulunmalıdır

Bu kalıpları tutarlı biçimde uyguladığınızda kabuk betikleriniz, daha üst düzey herhangi bir dilde yazılmış kod kadar modüler ve bakımı kolay olur.

Sıkça Sorulan Sorular

“Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma” dersi ücretsiz mi?

Evet — “Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma” 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.

“Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma” dersinde ne öğreneceğim?

Paylaşılan yardımcıları include korumaları ve ad alanlı işlev ön ekleri içeren, kaynaktan alınabilir .sh kitaplık dosyalarında düzenleyin. 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 2. dersidir.

“Yeniden Kullanılabilir Bash Kitaplıkları Oluşturma ve Kaynak Alma” 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