5. Robust skriptlar — set -euo pipefail
🎯 Bu bobda nimani o'rganasiz:
- Strict mode —
set -euo pipefailvaIFS=$'\n\t'chuqur tahlilgetopts— professional argument parsing- Logging — daraja, vaqt, rang, TTY detect bilan
- ShellCheck — bashning rasmiy lintera
- Security — quoting, command injection, secrets
- Production template — copy-paste qilsa bo'ladigan skelet
⏱ Vaqt: ~40 daqiqa 🧪 Mashqlar:
bashlings watch 10_robust(kelajak sprint)
5.1. Nima farqi bor — "ishlaydi" va "production-ready"?
# Versiya 1 — "ishlaydi"
cp /tmp/data.txt /var/backups/
# Versiya 2 — "production-ready"
set -euo pipefail
readonly SRC="/tmp/data.txt"
readonly DST="/var/backups/data_$(date +%Y%m%d).txt"
[[ -r "$SRC" ]] || { log_error "$SRC o'qib bo'lmadi"; exit 1; }
cp -p "$SRC" "$DST" || { log_error "Backup muvaffaqiyatsiz"; exit 1; }
log_info "✅ Backup: $DST"Ikkalasi ham bir xil ishni qiladi. Lekin ikkinchisi:
- Xato bo'lsa darhol to'xtaydi
- Aniqlanmagan o'zgaruvchini sezadi
- Xato sabablarini log'ga yozadi
- Manba mavjudligini oldindan tekshiradi
cpxato bo'lsa skript davom etmaydi- Foydalanuvchiga aniq feedback beradi
Bu bobning maqsadi — har bir skriptingizni versiya 1'dan versiya 2'ga aylantirish.
Qoida
Production skript = "ishlaydi" + "to'g'ri xatolik chiqaradi" + "xavfsiz" + "qayta ishga tushirib bo'ladi" + "tekshirib bo'ladi".
5.2. Strict mode — set -euo pipefail
Bashning eng kuchli (va eng kam ishlatiladigan) qatori:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'Buni har skript boshida yozish — DevOps olamining standartiga aylangan. Keling, har birini batafsil ko'ramiz.
set -e — birinchi xatoda to'xtash
Default Bash xulq-atvori — buyruq xato bersa davom etadi:
ls /yoq-katalog # xato
echo "Davom etyapman" # haligacha bajariladi!set -e bilan — birinchi xatoda darhol exit:
set -e
ls /yoq-katalog # bu yerda to'xtaydi
echo "Bu satrgacha yetmaydi"Bu yetarlimi? Yo'q — set -e ning nyuanslari
set -e ko'p holatda chetlab o'tiladi:
set -e
cmd || true # || dan keyin xato bekor qilinadi
cmd && other_cmd # ham bekor
if cmd; then # if shartda — bekor
...
fi
cmd | grep foo # ❌ cmd xatosi yashirinadi (pipefail kerak)
fn() { cmd; } # funksiya ichida — partialset -e bilan funksiya — diqqat
set -e
risky() {
cmd_that_fails
echo "Bu chiqadi yoki yo'q?"
}
risky || trueBash 4.4'gacha set -e funksiya ichida nostandart ishlardi. Hozir ham nyuanslari bor. Funksiyalar ichida aniq xato handling tavsiya etiladi.
set -u — aniqlanmagan o'zgaruvchi xato
set -u
echo "$undefined_var" # ❌ unbound variableBu typoлардан himoya qiladi:
set -u
name="Ali"
echo "Salom, $namr" # typo! → unbound variable xatosiset -u bilan ishlash texnikalari
Ba'zan o'zgaruvchi ixtiyoriy bo'lishi mumkin. Default qiymat patternini ishlating:
set -u
# ❌ Xato beradi:
echo "${OPT_VAR}"
# ✓ "qiymat berilmagan bo'lsa, bo'sh":
echo "${OPT_VAR:-}"
# ✓ Default qiymat:
echo "${OPT_VAR:-default}"
# ✓ Bo'sh emasligini tekshirish:
if [[ -z "${OPT_VAR:-}" ]]; then
echo "berilmagan"
fiset -o pipefail — pipeline ichidagi xatolarni ushlash
Default'da pipe xatosi yashirinadi — faqat oxirgi buyruqning exit code'i qaytariladi:
false | true # exit 0 ✓ (false yashirildi)
echo $? # 0
set -o pipefail
false | true # exit 1 (birinchi xato qaytariladi)
echo $? # 1Real misol:
# Bu xavfli — agar curl yiqilsa, jq ham 0 qaytaradi
curl https://api.com/data | jq .
# pipefail bilan curl xatosi sezish mumkin
set -o pipefail
curl https://api.com/data | jq .IFS=$'\n\t' — xavfsiz word-splitting
Default IFS — <space><tab><newline>. Bu — fayl nomlarida probel bo'lganda xavfli:
files="my file.txt other.txt"
for f in $files; do echo "$f"; done
# my
# file.txt
# other.txt ← "my file.txt" buzilgan!IFS=$'\n\t' — faqat newline va tab. Probel saqlanadi:
IFS=$'\n\t'
files=$'my file.txt\nother.txt'
for f in $files; do echo "$f"; done
# my file.txt
# other.txt ← to'g'ri!Skript boshida 4 qator
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'Bu — "Bash Strict Mode" — har production skript boshlanish formulasi.
5.3. Xatoliklarni boshqarish — strict mode'dan tashqari
set -e kuchli, lekin ba'zan xato kutilgan bo'ladi. Masalan, grep topmagan bo'lsa exit 1 qaytaradi — bu xato emas, bu natija.
|| — "xato bo'lsa default qiymat"
matches=$(grep "ERROR" log.txt) || matches="topilmadi"
if ! command -v jq &>/dev/null; then
echo "jq o'rnatilmagan" >&2
exit 1
fiif ! command — "buyruq xato bo'ldi"
if ! curl -fsS "https://api.com/" > response.json; then
echo "API yiqildi"
exit 1
fiset +e / set -e blok
Strict mode'ni vaqtincha o'chirib qo'yish:
set -e
some_critical_step
set +e # strict mode'ni o'chirish
optional_step_that_may_fail
maybe_fail
set -e # qaytarishERR trap — markaziy xatolik handler
#!/usr/bin/env bash
set -euo pipefail
error_handler() {
local line=$1
local cmd=$2
echo "❌ Xato $line qatorida: $cmd" >&2
exit 1
}
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
# Bu yerda xato sodir bo'lsa, handler chaqiriladi5.4. Idempotent skriptlar
Idempotent — bir necha marta ishga tushirsangiz ham bir xil natija beradigan skript. Production'ning oltin qoidasi.
Misol — toza emas (idempotent emas)
mkdir /var/myapp # ikkinchi marta xato beradi
adduser myapp # ikkinchi marta xato beradi
echo "config" > /etc/myapp.conf # eskini almashtiradiIdempotent variant
mkdir -p /var/myapp # mavjud bo'lsa OK
id myapp &>/dev/null || adduser myapp # faqat yo'q bo'lsa
[[ -f /etc/myapp.conf ]] || echo "config" > /etc/myapp.confState marker pattern
readonly MARKER="/var/run/migration_v2.done"
if [[ -f "$MARKER" ]]; then
echo "Migration allaqachon bajarilgan"
exit 0
fi
# ... migration ishi ...
touch "$MARKER"
echo "✅ Tugadi"Lock fayl — bitta nusxa kafolati
(4-bobdan tanish — bu yerda yana bir bor)
readonly LOCKFILE="/tmp/myapp.lock"
if [[ -f "$LOCKFILE" ]] && kill -0 "$(cat "$LOCKFILE")" 2>/dev/null; then
echo "Allaqachon ishlamoqda"
exit 0
fi
echo $$ > "$LOCKFILE"
trap 'rm -f "$LOCKFILE"' EXIT5.5. Logging — production sifati
printf vs echo
echo -e "Salom\tdunyo" # ❌ -e portable emas (BSD/POSIX farqlari)
printf 'Salom\tdunyo\n' # ✓ har joyda ishlaydiQoida: har doim printf ishlating. echo faqat oddiy stringlar uchun.
Log levels va timestamp
log_debug() { [[ "${DEBUG:-0}" == "1" ]] && printf '[%s] [DEBUG] %s\n' "$(date +%T)" "$*" >&2; }
log_info() { printf '[%s] [INFO] %s\n' "$(date +%T)" "$*"; }
log_warn() { printf '[%s] [WARN] %s\n' "$(date +%T)" "$*" >&2; }
log_error() { printf '[%s] [ERROR] %s\n' "$(date +%T)" "$*" >&2; }Ishlatish:
log_info "Server boshlandi"
log_warn "Disk 80% to'lgan"
log_error "Database javob bermayapti"
DEBUG=1 ./script.sh # debug yoqilganRang — faqat TTY bo'lsa
if [[ -t 1 ]]; then # stdout TTY mi?
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
RESET='\033[0m'
else
RED='' GREEN='' YELLOW='' RESET=''
fi
log_info() { printf '%b[%s] [INFO]%b %s\n' "$GREEN" "$(date +%T)" "$RESET" "$*"; }
log_warn() { printf '%b[%s] [WARN]%b %s\n' "$YELLOW" "$(date +%T)" "$RESET" "$*" >&2; }
log_error() { printf '%b[%s] [ERROR]%b %s\n' "$RED" "$(date +%T)" "$RESET" "$*" >&2; }[[ -t 1 ]] — stdout terminal'mi? Pipe yoki faylga yozilsa rang qo'shilmaydi (toza log fayllar).
logger — syslog'ga yozish
logger -t myapp "Server boshlandi"
# /var/log/syslog'ga yoziladi (Linux)
# Tag: myapp5.6. getopts — professional argument parsing
$1, $2, $3 qo'l bilan o'qish — oddiy skriptlar uchun. Bir nechta flag kerak bo'lsa — getopts ishlatamiz.
Asosiy sintaksis
verbose=0
output=""
while getopts ":vo:h" opt; do
case "$opt" in
v) verbose=1 ;;
o) output="$OPTARG" ;;
h) echo "Yordam"; exit 0 ;;
\?) echo "Noma'lum flag: -$OPTARG" >&2; exit 2 ;;
:) echo "Flag -$OPTARG argument talab qiladi" >&2; exit 2 ;;
esac
done
shift $((OPTIND - 1)) # parse qilingan flag'larni $@ dan olib tashlaydiFormat string'ni o'qish
":vo:h":
- Boshidagi
:— silent error mode (biz xatolarni o'zimiz chiqaramiz) v— flag (argumentsiz)o:— flag + argument (:keyin)h— flag (argumentsiz)
Real misol
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<EOF
Foydalanish: $0 [-v] [-o FAYL] [-h] INPUT
Variantlar:
-v Verbose rejim
-o FAYL Natija fayli (default: stdout)
-h Yordam
EOF
}
verbose=0
output=""
while getopts ":vo:h" opt; do
case "$opt" in
v) verbose=1 ;;
o) output="$OPTARG" ;;
h) usage; exit 0 ;;
\?) echo "❌ Noma'lum flag: -$OPTARG" >&2; usage; exit 2 ;;
:) echo "❌ -$OPTARG argument talab qiladi" >&2; exit 2 ;;
esac
done
shift $((OPTIND - 1))
if [[ $# -lt 1 ]]; then
echo "❌ INPUT argument zarur" >&2
usage
exit 2
fi
input="$1"
[[ $verbose -eq 1 ]] && echo "Verbose yoqildi, input=$input"Foydalanish:
./script.sh -v -o result.txt input.txt
./script.sh -h
./script.sh -x # → Noma'lum flag: -xgetopts cheklovlari
- Faqat qisqa flag (
-v,-o) qo'llab-quvvatlaydi - Long flag (
--verbose) kerak bo'lsa —getopt(BSD/GNU farqli) yoki qo'l parsing
5.7. Konfiguratsiya — environment vs CLI
Environment variables — sozlash uchun
LOG_LEVEL="${LOG_LEVEL:-info}"
TIMEOUT="${TIMEOUT:-30}"
API_URL="${API_URL:-https://api.example.com}"Foydalanish:
LOG_LEVEL=debug ./script.sh
TIMEOUT=60 ./script.shKonfiguratsiya fayli — source
# ~/.myapp/config
LOG_LEVEL=debug
API_URL=https://prod.example.com
TIMEOUT=60# script.sh
[[ -f ~/.myapp/config ]] && source ~/.myapp/config
LOG_LEVEL="${LOG_LEVEL:-info}".env fayl
# .env
DATABASE_URL=postgres://localhost/myapp
SECRET_KEY=xyz123# Load only if .env exists
if [[ -f .env ]]; then
set -a # avtomatik export
source .env
set +a
fi.env ni gitignore ga qo'shing
Secrets fayllarni hech qachon repository'ga commit qilmang. .gitignore'da .env bo'lishi shart.
5.8. ShellCheck — bashning rasmiy linteri
shellcheck — Bash skriptlardagi xatoliklarni va anti-pattern'larni statik tahlil qiladi. Production skript yozasizmi — shellchecksiz emas.
O'rnatish
# macOS
brew install shellcheck
# Ubuntu/Debian
sudo apt install shellcheck
# Web variant (sinov uchun)
# https://www.shellcheck.net/Ishlatish
shellcheck script.shMisol xato
# bad.sh
name=$1
echo "Salom $name"
rm $name$ shellcheck bad.sh
In bad.sh line 2:
name=$1
^-- SC2086: Double quote to prevent globbing and word splitting.
In bad.sh line 3:
echo "Salom $name"
^-- SC2086: ...
In bad.sh line 4:
rm $name
^-- SC2086: Double quote to prevent globbing and word splitting.Tuzatilgan versiya:
name="$1"
echo "Salom $name" # ichida bor — OK
rm "$name" # quote qilinganEng ko'p uchraydigan warninglar
| Kod | Mazmuni |
|---|---|
| SC2086 | Tirnoqsiz o'zgaruvchi — quote qiling |
| SC2155 | local var=$(cmd) — exit code yutiladi |
| SC2046 | $(cmd) ni quote qiling |
| SC2034 | Ishlatilmagan o'zgaruvchi |
| SC2164 | cd ning xatosini handle qiling |
| SC2181 | [[ $? ... ]] o'rniga if cmd ishlating |
| SC2207 | arr=($(cmd)) — mapfile -t ishlating |
Selektiv suppression
Ba'zan ataylab "noto'g'ri" yozasiz — masalan, intentional word-splitting:
# shellcheck disable=SC2086
echo $unquoted_intentional# shellcheck directive — bu kommentar, lekin shellcheck buni o'qiydi.
CI'da majburiy qiling
GitHub Actions / GitLab CI da shellcheck *.sh qadamini qo'shing. Pull request'da xato bo'lsa CI yiqiladi — bu sifatni darhol oshiradi.
5.9. Testing — bats-core
Skriptlarni avtomatik test qilish uchun bats (Bash Automated Testing System) — eng mashhuri.
O'rnatish
brew install bats-coreTest misoli
# tests/test_math.bats
@test "yigindi 2 va 3" {
result=$(./math.sh 2 3)
[ "$result" = "5" ]
}
@test "salbiy sonlar ishlaydi" {
result=$(./math.sh -2 5)
[ "$result" = "3" ]
}
@test "argumentsiz xato beradi" {
run ./math.sh
[ "$status" -ne 0 ]
}Ishlatish
bats tests/
# ✓ yigindi 2 va 3
# ✓ salbiy sonlar ishlaydi
# ✓ argumentsiz xato beradi
# 3 tests, 0 failuresCI integratsiya
# .github/workflows/test.yml
- run: bats tests/
- run: shellcheck *.sh5.10. Xavfsizlik — production'ning eng muhim qismi
1. Har doim quote qiling
file="$1"
rm $file # ❌ "my file.txt" → ikki argument
rm "$file" # ✓2. Command injection xavfi
# ❌ XAVFLI
read -p "Fayl nomi: " name
ls $name
# Agar foydalanuvchi "; rm -rf /" yozsa — disaster
# ✓ XAVFSIZ
read -p "Fayl nomi: " name
ls "$name"3. eval dan qoching
eval "$user_input" # ❌ HECH QACHON4. mktemp — xavfsiz vaqtinchalik fayllar
# ❌ Predictable, xavfli
tmpfile=/tmp/myapp.tmp
# ✓ Tasodifiy, atomic
tmpfile=$(mktemp)
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpfile" "$tmpdir"' EXIT5. Secrets bilan ishlash
# ❌ Hech qachon parol skript ichida
DB_PASSWORD="hardcoded123"
# ✓ Environment'dan
DB_PASSWORD="${DB_PASSWORD:?DB_PASSWORD o'rnatilmagan}"
# ✓ Yoki secrets manager (vault, AWS Secrets, ...)
DB_PASSWORD=$(aws secretsmanager get-secret-value --secret-id db --query SecretString --output text)6. Fayl ruxsatlari
umask 077 # yaratilgan fayllar 600 bo'ladi (faqat ega o'qiydi)
tmpfile=$(mktemp)
echo "secret" > "$tmpfile"
ls -l "$tmpfile" # -rw-------7. set -u xavfsizlik foydasi
set -u
rm -rf "$WORK_DIR"/* # WORK_DIR aniqlanmagan bo'lsa — XATO, root o'chmaydiBu — rm -rf / kabi disasterlardan saqlovchi muhim mexanizm.
5.11. Dokumentatsiya va help
Usage pattern
usage() {
cat <<EOF
$(basename "$0") — qisqa tavsif
FOYDALANISH:
$(basename "$0") [VARIANTLAR] ARGUMENTLAR
VARIANTLAR:
-h Bu yordam matnini ko'rsatish
-v Verbose rejim
-o FAYL Natija fayli
MISOLLAR:
$(basename "$0") -v input.txt
$(basename "$0") -o result.txt data.csv
EOF
}Inline kommentlar
Yaxshi:
# Eski (>30 kun) backuplarni tozalash
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -deleteYomon:
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete # find ishlatadiKommentar NIMA UCHUNni tushuntirsin, NIMAni emas (kod o'zi aytadi).
5.12. Real misol — Production-Ready Template
Bu — copy-paste qilsa bo'ladigan skelet. Hammasi birga:
#!/usr/bin/env bash
#
# my-script.sh — qisqa tavsif (bir-ikki qator)
#
# Foydalanish:
# ./my-script.sh [-v] [-o output] <input>
#
# === Strict mode ===
set -euo pipefail
IFS=$'\n\t'
# === Konstantalar ===
readonly SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="${LOG_FILE:-/tmp/${SCRIPT_NAME%.sh}.log}"
# === Ranglar (faqat TTY uchun) ===
if [[ -t 1 ]]; then
readonly RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' DIM='\033[2m' RESET='\033[0m'
else
readonly RED='' GREEN='' YELLOW='' DIM='' RESET=''
fi
# === Logging ===
_log() {
local level="$1" color="$2"; shift 2
local line
line=$(printf '[%s] [%-5s] %s' "$(date '+%Y-%m-%d %H:%M:%S')" "$level" "$*")
printf '%b%s%b\n' "$color" "$line" "$RESET" >&2
printf '%s\n' "$line" >> "$LOG_FILE"
}
log_debug() { [[ "${DEBUG:-0}" == "1" ]] && _log DEBUG "$DIM" "$@"; }
log_info() { _log INFO "$GREEN" "$@"; }
log_warn() { _log WARN "$YELLOW" "$@"; }
log_error() { _log ERROR "$RED" "$@"; }
die() { log_error "$@"; exit 1; }
# === Cleanup ===
__cleaned=0
cleanup() {
local rc=$?
[[ $__cleaned -eq 1 ]] && return
__cleaned=1
# tmp fayllar, lock fayllar va boshqa resurslarni tozalash
[[ -n "${TMPDIR_:-}" && -d "$TMPDIR_" ]] && rm -rf "$TMPDIR_"
if [[ $rc -eq 0 ]]; then
log_info "Yakunlandi (success)"
elif [[ $rc -eq 130 ]]; then
log_warn "Foydalanuvchi to'xtatdi"
else
log_error "Exit code: $rc"
fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
trap 'die "Xato $LINENO qatorida: $BASH_COMMAND"' ERR
# === Usage ===
usage() {
cat <<EOF
$SCRIPT_NAME — qisqa tavsif
FOYDALANISH:
$SCRIPT_NAME [VARIANTLAR] <input>
VARIANTLAR:
-v Verbose rejim
-o FAYL Natija fayli (default: stdout)
-h Bu yordam
MUHIT O'ZGARUVCHILARI:
DEBUG=1 Debug logni yoqish
LOG_FILE Log fayl yo'li (default: /tmp/$SCRIPT_NAME.log)
EOF
}
# === Argument parsing ===
verbose=0
output=""
while getopts ":vo:h" opt; do
case "$opt" in
v) verbose=1 ;;
o) output="$OPTARG" ;;
h) usage; exit 0 ;;
\?) die "Noma'lum flag: -$OPTARG" ;;
:) die "Flag -$OPTARG argument talab qiladi" ;;
esac
done
shift $((OPTIND - 1))
[[ $# -lt 1 ]] && { usage; die "Input zarur"; }
readonly INPUT="$1"
# === Asosiy ish ===
main() {
log_info "Boshlandi: $INPUT"
[[ $verbose -eq 1 ]] && log_info "Verbose yoqildi"
[[ -r "$INPUT" ]] || die "Topilmadi yoki o'qib bo'lmaydi: $INPUT"
# Vaqtinchalik katalog
TMPDIR_=$(mktemp -d)
log_debug "Tmp: $TMPDIR_"
# ... haqiqiy ish bu yerda ...
log_info "Tugadi"
}
main "$@"Bu shablon nima qiladi?
| Element | Foyda |
|---|---|
set -euo pipefail | Strict mode — xato yashirinmaydi |
IFS=$'\n\t' | Probelli fayllar bilan xavfsiz |
readonly konstantalar | Skript holatini barqaror saqlash |
| TTY-aware ranglar | Terminal va fayl ikkalasiga to'g'ri yozish |
| Logging — 4 daraja | Production tahlil uchun |
| Cleanup + 4 trap | Har vaziyatda toza yakunlanish |
usage() + -h | O'z-o'zini hujjatlaydigan |
getopts | Professional argument parsing |
main "$@" | Asosiy mantiq bitta funksiyada — test qilish oson |
Foydalanish
Bu shablonni template.sh deb saqlang. Yangi skript yozayotganda nusxa olib boshlang. 80% vazifa allaqachon bajarilgan.
5.13. Tez-tez uchraydigan xatolar
Top 10 production tuzoq
set -emavjud emas. Skript silently xato qoldiradi. Har doim qo'shing.set -umavjud emas. Typo'lar oson o'tib ketadi.set -o pipefailunutilgan. Pipeline xatolari ko'rinmaydi.Tirnoqsiz o'zgaruvchi.
rm $file— probelli fayllar buziladi.local r=$(cmd)— exit code yutilgan.bashlocal r # avval e'lon r=$(cmd) # keyin to'ldirish/dev/nullga stderr unutilgan.ls /yoq 2>/dev/null— sukut bilan o'tkazish kerak.ShellCheckishlatilmagan. 80% xato avtomatik aniqlanadi.cdxatosi handle qilinmagan.bashcd "$dir" || die "cd xatosi: $dir"evalishlatilgan. Command injection — qoching.Hardcoded fayl yo'llari.
/Users/mac/...— boshqa kompyuterda ishlamaydi.$HOME,$(dirname "$0")ishlating.
5.14. Mashqlar
🧪 Kelajakda
bashlings watch 10_robustpaketida.
Strict-mode lab — quyidagi skript faqat strict mode'da xato beradi. Sababini tushuntiring va tuzating:
bash#!/usr/bin/env bash name="${name}" files=$(ls /yoq) echo "tugadi"ShellCheck cleanup —
shellcheck --severity=warningbilan tekshirib, xatosiz holatga keltirsin:bash#!/bin/bash for f in $(ls *.log); do cp $f /backup/ echo "Done $f" donegetoptsparser —-c COUNT,-d DELAY,-v,-hflaglarini qo'llab-quvvatlovchi skript yozing.Idempotent installer —
nginxo'rnatuvchi skript yozing. Bir necha marta ishga tushirish xavfsiz bo'lsin (allaqachon o'rnatilgan bo'lsa xato bermasin).Production template — yuqoridagi shablonni nusxalab, oddiy "Hello, World" skripti yozing. ShellCheck'dan o'tsin.
5.15. Xulosa
Production-ready skript checklist
- [ ] Shebang:
#!/usr/bin/env bash - [ ] Strict mode:
set -euo pipefail - [ ] Xavfsiz IFS:
IFS=$'\n\t' - [ ]
readonlykonstantalar - [ ] Logging — kamida 3 daraja (info/warn/error)
- [ ] Cleanup
trap EXIT - [ ]
INT/TERMgraceful handling - [ ]
usage()+-hflag - [ ]
getoptsbilan argument parsing - [ ] Hamma o'zgaruvchi quote qilingan:
"$var" - [ ]
mktemporqali tmp fayllar - [ ] ShellCheck'dan o'tadi (
shellcheck0 warning) - [ ] Asosiy ish
main()funksiyasida - [ ] Test (bats-core)
10 ta oltin qoida
| # | Qoida |
|---|---|
| 1 | set -euo pipefail har doim |
| 2 | Har o'zgaruvchini quote qiling: "$var" |
| 3 | mktemp ishlatib tmp fayllar |
| 4 | trap cleanup EXIT |
| 5 | ShellCheck — har commit oldidan |
| 6 | getopts orqali argumentlar |
| 7 | printf (echo emas) |
| 8 | [[ ]] ([ ] emas) |
| 9 | $(...) (`cmd` emas) |
| 10 | "Magic numbers" yo'q — readonly konstantalar |
🎉 2-qism tugadi!
Tabriklaymiz! Siz quyidagilarni o'zlashtirdingiz:
| Bob | Mavzu | Ko'nikma |
|---|---|---|
| 1 | Funksiyalar | Kodni qayta ishlatish |
| 2 | Massivlar | Strukturali ma'lumot |
| 3 | sed va awk | Industrial matn qayta ishlash |
| 4 | Signallar va traps | Hayotiy cleanup |
| 5 | Robust skriptlar | Production-grade kod |
Endi siz professional Bash dasturchisiz. DevOps, SRE, sistema administrator — har qanday rolda kerakli vositalar qo'lingizda.
Keyingi qadamlar
- Mashq qilish: har real loyihada Bash o'rniga Python yoki Go o'ylashdan oldin — Bashda hal qila olishingizni sinab ko'ring
- Kitobxonlik: Google Shell Style Guide, Bash Pitfalls
- Bash kelajakni o'rganing —
coproc,<()process substitution chuqurroq,mapfileflaglari - 3-qism (Part 3) —
curl,ssh,jq,cron,docker, CI/CD bilan integratsiya
Yaxshi yo'l! 🚀
Yana ko'p ishlash bor — lekin asos endi mustahkam.