Reusable Bash Libraries बनाना और Source करना
साझा helpers को include guards और namespaced function prefixes वाली sourceable .sh library files में व्यवस्थित करें।
Reusable Bash Libraries बनाना और Source करना, CoddyKit पर DevOps बूटकैंप का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह DevOps बूटकैंप सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
Bash लाइब्रेरी क्या है
सॉफ़्टवेयर इंजीनियरिंग में लाइब्रेरी पुनः उपयोग योग्य फ़ंक्शन का संग्रह होती है, जिसे कई प्रोग्राम साझा कर सकते हैं। Bash में भी यही अवधारणा स्रोत से लोड की जा सकने वाली शेल स्क्रिप्ट के माध्यम से उपलब्ध है।
हर स्क्रिप्ट में सहायक फ़ंक्शन की प्रतिलिपि बनाने के बजाय, उन्हें एक समर्पित .sh फ़ाइल में रखें और source कमांड (या इसके संक्षिप्त रूप .) से लोड करें। उस फ़ाइल में परिभाषित कोई भी फ़ंक्शन, चर या उपनाम कॉल करने वाली स्क्रिप्ट के वर्तमान शेल सत्र में उपलब्ध हो जाता है।
- DRY सिद्धांत (अपने आपको दोहराएँ नहीं) को बढ़ावा देता है
- बग सुधारों को केंद्रीकृत करता है — एक बार सुधारें, सभी कॉल करने वालों को लाभ मिले
- अलग-अलग स्क्रिप्ट को छोटा और पढ़ने में आसान बनाता है
- लॉगिंग, त्रुटि प्रबंधन और उपयोगिता तर्क में पूरी टीम के लिए सुसंगतता संभव बनाता है
अच्छी तरह व्यवस्थित Bash प्रोजेक्ट में आम तौर पर इन साझा फ़ाइलों वाली lib/ निर्देशिका होती है, जो उच्च-स्तरीय भाषाओं की परंपराओं जैसी होती है।
source कमांड और डॉट ऑपरेटर
वर्तमान शेल वातावरण में लाइब्रेरी फ़ाइल लोड करने के दो समान तरीके हैं:
source /path/to/lib.sh— स्पष्ट और पढ़ने योग्य रूप. /path/to/lib.sh— POSIX-संगत संक्षिप्त रूप
दोनों फ़ाइल को वर्तमान शेल प्रक्रिया में चलाते हैं, सबशेल में नहीं, इसलिए उसमें परिभाषित हर फ़ंक्शन और चर कॉल के तुरंत बाद आपकी स्क्रिप्ट के वातावरण का हिस्सा बन जाता है।
एक सामान्य तरीका $BASH_SOURCE का उपयोग करके लाइब्रेरी को कॉल करने वाली स्क्रिप्ट के सापेक्ष ढूँढना है। इससे प्रोजेक्ट को कहीं भी स्थापित करने पर वह पोर्टेबल रहता है।
#!/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"अपनी पहली लाइब्रेरी फ़ाइल बनाना
लाइब्रेरी फ़ाइल एक साधारण .sh फ़ाइल होती है, जिसमें केवल फ़ंक्शन परिभाषाएँ (और कभी-कभी स्थिरांक) होते हैं। इसे शीर्ष स्तर पर कोई दुष्प्रभाव उत्पन्न करने वाला कोड नहीं चलाना चाहिए — इसका उद्देश्य स्रोत से लोड होना है, सीधे चलना नहीं।
मुख्य परंपराएँ:
- लाइब्रेरी का उद्देश्य बताने वाली शेबांग टिप्पणी से शुरू करें
- केवल फ़ंक्शन परिभाषित करें — शीर्ष स्तर पर कोई
mainतर्क नहीं - फ़ंक्शन के अंदर
returnका उपयोग करें (exitका कभी नहीं, क्योंकि वह कॉल करने वाले को बंद कर देगा) - फ़ाइल को अपने प्रोजेक्ट की
lib/उपनिर्देशिका में रखें
#!/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
}शामिल करने के सुरक्षा उपाय: दोबारा स्रोत से लोड होने से रोकना
जब कई स्क्रिप्ट एक ही लाइब्रेरी को स्रोत से लोड करती हैं, या कोई लाइब्रेरी ऐसी दूसरी लाइब्रेरी को स्रोत से लोड करती है जिसे मुख्य स्क्रिप्ट भी लोड करती है, तो फ़ंक्शन कई बार परिभाषित हो सकते हैं। इससे समय व्यर्थ होता है और यदि फ़ंक्शन का मुख्य भाग चलते समय बदल दिया जाए, तो सूक्ष्म बग उत्पन्न हो सकते हैं।
इसका समाधान शामिल करने का सुरक्षा उपाय है — एक ऐसा चर जो संकेतक की तरह काम करता है। पहली बार लोड होने पर चर निर्धारित नहीं होता, इसलिए फ़ाइल आगे चलती है। हर अगली बार सुरक्षा चर पहले से निर्धारित होता है, इसलिए फ़ाइल तुरंत लौट आती है।
यह C/C++ में #pragma once या अन्य भाषाओं में if not already imported तरीकों के समान Bash तरीका है।
#!/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
}नेमस्पेस वाले फ़ंक्शन उपसर्ग
Bash में फ़ंक्शन के लिए एक ही वैश्विक नेमस्पेस होता है। यदि दो लाइब्रेरी log या init नाम का फ़ंक्शन परिभाषित करती हैं, तो दूसरी परिभाषा चुपचाप पहली को अधिलेखित कर देती है।
मानक बचाव नेमस्पेस उपसर्ग है: लाइब्रेरी के हर फ़ंक्शन के नाम के आगे लाइब्रेरी का संक्षिप्त नाम और उसके बाद दो कोलन (::) या अंडरस्कोर लगाया जाता है। उदाहरण के लिए, स्ट्रिंग उपयोगिता लाइब्रेरी str:: और फ़ाइल लाइब्रेरी file:: का उपयोग करती है।
- टकराव की संभावना अत्यंत कम हो जाती है
- कॉल करने वाला कोड स्वयं अपना विवरण देता है —
str::trimआपको ठीक-ठीक बताता है कि फ़ंक्शन कहाँ है - Grep से खोजने की सुविधा बेहतर होती है:
grep 'str::' main.shतुरंत स्ट्रिंग-लाइब्रेरी की सभी कॉल दिखाता है
#!/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/ निर्देशिका व्यवस्थित करना
जैसे-जैसे प्रोजेक्ट बढ़ता है, एकल utils.sh को संभालना कठिन हो जाता है। lib/ निर्देशिका के अंदर ज़िम्मेदारियों को केंद्रित लाइब्रेरी फ़ाइलों में बाँटें:
lib/log.sh— लॉगिंग सहायक (log::info,log::warn,log::error)lib/str.sh— स्ट्रिंग में हेरफेर (str::trim,str::upper)lib/fs.sh— फ़ाइल-प्रणाली सहायक (fs::require_dir,fs::safe_rm)lib/net.sh— नेटवर्क जाँच (net::wait_for_port,net::is_online)
एकल बूटस्ट्रैप लोडर फ़ाइल (lib/bootstrap.sh) इन सभी को सही क्रम में स्रोत से लोड कर सकती है, इसलिए हर स्क्रिप्ट में केवल एक बार स्रोत-लोड कमांड की आवश्यकता होती है।
#!/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."एक पूर्ण लॉगिंग लाइब्रेरी
लॉगिंग ऐसी चिंता है जो स्क्रिप्टों में सबसे अधिक साझा की जाती है। एक समर्पित lib/log.sh आउटपुट का प्रारूप, लॉग स्तर और रंग कोड एक ही स्थान पर व्यवस्थित करती है।
ऐसी लाइब्रेरी के होने पर प्रोजेक्ट की हर स्क्रिप्ट बिना किसी प्रारूपण कोड को दोहराए, एकसमान, समय-मुद्रित और रंग-कोडित संदेश प्रिंट करती है।
#!/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; }फ़ाइल सिस्टम सहायक लाइब्रेरी
फ़ाइलों और डायरेक्टरी में बदलाव करने वाली स्क्रिप्टें अक्सर वही रक्षात्मक जाँच दोहराती हैं: क्या यह डायरेक्टरी मौजूद है? क्या इस पथ पर लिखा जा सकता है? क्या मैं किसी महत्वपूर्ण चीज़ को मिटाने वाला हूँ?
इन जाँचों को lib/fs.sh में एक ही स्थान पर रखने से हर उपयोगकर्ता स्क्रिप्ट अधिक सुरक्षित और पढ़ने में आसान बनती है। ध्यान दें कि हर फ़ंक्शन विफलता पर exit के बजाय return 1 का उपयोग करता है, जिससे कॉल करने वाली स्क्रिप्ट त्रुटि को उचित ढंग से संभाल सकती है।
#!/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
}
}एक स्थिरांक के साथ अपनी लाइब्रेरी का संस्करण प्रबंधित करना
जब आपकी लाइब्रेरियाँ कई प्रोजेक्टों में साझा की जाती हैं या किसी टीम को वितरित की जाती हैं, तब यह जानना महत्वपूर्ण हो जाता है कि रनटाइम पर लाइब्रेरी का कौन-सा संस्करण लोड हुआ है। एक सरल परंपरा यह है कि हर लाइब्रेरी से एक संस्करण स्थिरांक निर्यात किया जाए।
इसके बाद कॉल करने वाली स्क्रिप्टें प्रारंभ में न्यूनतम संस्करण की पुष्टि कर सकती हैं और बाद में रहस्यमय विफलताओं को डीबग करने के बजाय असंगतियों को जल्दी पकड़ सकती हैं। सुरक्षा चर संस्करण स्ट्रिंग का भी काम करता है, जिससे एक ही चर में दो जिम्मेदारियाँ पूरी होती हैं।
#!/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"
}एक स्व-निहित प्रदर्शन: कई लाइब्रेरियों का उपयोग
यह दृश्य एक वास्तविक जैसी स्क्रिप्ट दिखाता है, जो दो लाइब्रेरियों को स्रोत करती है और दोनों के फ़ंक्शनों का उपयोग करती है। ध्यान दें कि मुख्य स्क्रिप्ट साफ़ रहती है — वह उद्देश्य व्यक्त करती है, जबकि कार्यान्वयन का पूरा विवरण लाइब्रेरियों में रहता है।
यह स्क्रिप्ट स्वतंत्र फ़ाइल के रूप में चलाई जा सकती है, क्योंकि यह अस्थायी फ़ाइलों में लिखे गए here-documents का उपयोग करके लाइब्रेरियों को उसी में परिभाषित करती है। वास्तविक प्रोजेक्ट में हर लाइब्रेरी lib/ के अंतर्गत अपनी अलग फ़ाइल में रहती।
#!/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")'"सर्वोत्तम अभ्यास और सामान्य समस्याएँ
किसी लाइब्रेरी को टीम के उपयोग के लिए जारी करने से पहले यह जाँच-सूची देखें:
- समावेशन सुरक्षा — हर लाइब्रेरी में यह अवश्य होना चाहिए; सुरक्षा चर का नाम सबसे ऊपर लिखें
- शीर्ष-स्तरीय कोई अप्रत्याशित प्रभाव नहीं — किसी फ़ंक्शन के बाहर कभी भी
cd,echoया वैश्विक स्थिति में बदलाव न करें - फ़ंक्शनों के अंदर सभी चरों के लिए
localका उपयोग करें —localके बिना हर असाइनमेंट कॉल करने वाली स्क्रिप्ट के क्षेत्र में फैल जाता है - वापस लौटाएँ, कभी बाहर न निकलें — स्रोत की गई फ़ाइल के अंदर
exitपूरी कॉल करने वाली शेल को समाप्त कर देता है - इनपुट की जाँच करें — आवश्यक तर्कों की जाँच करें और उनके न होने पर अर्थपूर्ण त्रुटि कोड लौटाएँ
- टिप्पणियों के साथ दस्तावेज़ लिखें — हर फ़ंक्शन का कार्य, उसके पैरामीटर और उसका लौटाया गया मान बताएँ
- लाइब्रेरी फ़ाइलों के अंदर
set -eसे बचें — कॉल करने वाली स्क्रिप्ट की अपनी त्रुटि-संभाल रणनीति हो सकती है; निर्णय उसे लेने दें
ज्ञान जाँच: समावेशन सुरक्षा
ऐसे प्रोजेक्ट पर विचार करें जिसमें main.sh, lib/bootstrap.sh और lib/log.sh दोनों को स्रोत करती है, और lib/bootstrap.sh भी आंतरिक रूप से lib/log.sh को स्रोत करती है। lib/log.sh में समावेशन सुरक्षा का मुख्य उद्देश्य क्या है?
पाठ का पुनरावलोकन: Bash लाइब्रेरियाँ सही ढंग से बनाना
आपने पुनः उपयोग योग्य Bash लाइब्रेरियाँ बनाने और उनका उपयोग करने की सभी आवश्यक तकनीकें सीख ली हैं। मुख्य बातें ये हैं:
sourceया.से स्रोत करें — यह फ़ाइल को वर्तमान शेल में लोड करता है, जिससे उसके फ़ंक्शन तुरंत उपलब्ध हो जाते हैं- लाइब्रेरी के पथ को कॉल करने वाली स्क्रिप्ट के सापेक्ष निर्धारित करने के लिए
$BASH_SOURCEका उपयोग करें, ताकि प्रोजेक्ट पोर्टेबल रहें - समावेशन सुरक्षा (
[[ -n "${_GUARD:-}" ]] && return 0) एक ही लाइब्रेरी को कई फ़ाइलों द्वारा स्रोत किए जाने पर परिभाषाओं की पुनरावृत्ति रोकती है - नामस्थान उपसर्ग (
log::,str::,fs::) लाइब्रेरियों के बीच फ़ंक्शन नामों के टकराव समाप्त करते हैं - केंद्रित और एकल-जिम्मेदारी वाली फ़ाइलों से बनी
lib/डायरेक्टरी बड़े प्रोजेक्टों का रखरखाव आसान बनाती है - एक बूटस्ट्रैप लोडर (
lib/bootstrap.sh) हर स्क्रिप्ट को पूरे तंत्र को लोड करने के लिए एक ही स्रोत कॉल देता है - लाइब्रेरी फ़ाइलों में कभी
exitया शीर्ष-स्तरीय अप्रत्याशित प्रभावों का उपयोग न करें — वहाँ केवल फ़ंक्शन परिभाषाएँ और स्थिरांक होने चाहिए
इन तरीकों को लगातार अपनाएँ और आपकी शेल स्क्रिप्टें किसी भी उच्च-स्तरीय भाषा में लिखे कोड जितनी मॉड्यूलर और रखरखाव योग्य बन जाएँगी।
एआई शिक्षक के साथ DevOps बूटकैंप सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 142
- पाठ
- 568
अक्सर पूछे जाने वाले प्रश्न
क्या “Reusable Bash Libraries बनाना और Source करना” पाठ निःशुल्क है?
हाँ — DevOps बूटकैंप अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “Reusable Bash Libraries बनाना और Source करना” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। DevOps बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“Reusable Bash Libraries बनाना और Source करना” में मैं क्या सीखूँगा?
साझा helpers को include guards और namespaced function prefixes वाली sourceable .sh library files में व्यवस्थित करें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ DevOps बूटकैंप का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या DevOps बूटकैंप शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर DevOps बूटकैंप शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।
“Reusable Bash Libraries बनाना और Source करना” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस DevOps बूटकैंप पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर DevOps बूटकैंप पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- Local Scope और Return Codes से Functions का डिज़ाइन
- Reusable Bash Libraries बनाना और Source करना
- getopts से Flags और Arguments को Parse करना
- Functions के बीच Arrays और Associative Maps भेजना