Mashqlar — zaxira nusxa skripti
Muammodan boshlaylik
Siz kichik do'kon saytining yagona administratorisiz. Sizga kerak:
- Har kecha sayt fayllari va bazaning zaxira nusxasi, eski nusxalarni avtomatik tozalash bilan
- Har 5 daqiqada tekshiruv: sayt javob beryaptimi, disk to'lmayaptimi — muammo bo'lsa, Telegram ga xabar
Bu — 37–40-darslarning hammasi: o'zgaruvchilar, shartlar, tsikllar, funksiyalar, set -euo pipefail, trap va rejalashtirish. Har bir mashqni avval o'zingiz yozing.
Tayyorgarlik — sinov "sayti":
mkdir -p ~/mashq-skript/sayt/{uploads,config} && cd ~/mashq-skript
for i in $(seq 1 20); do head -c 50K /dev/urandom > "sayt/uploads/rasm-$i.jpg"; done
echo "DB_HOST=localhost" > sayt/config/.env
echo "<h1>Dokon</h1>" > sayt/index.html
1-mashq: Oddiy zaxira
zaxira.sh skriptini yozing:
sayt/papkasinizaxiralar/sayt_YYYY-MM-DD_HHMM.tar.gzga arxivlaydizaxiralarpapkasi yo'q bo'lsa — yaratadi- Oxirida fayl nomi va hajmini chiqaradi
Yechim
#!/usr/bin/env bash
set -euo pipefail
MANBA="$HOME/mashq-skript/sayt"
MANZIL="$HOME/mashq-skript/zaxiralar"
FAYL="$MANZIL/sayt_$(date +%F_%H%M).tar.gz"
mkdir -p "$MANZIL"
tar -czf "$FAYL" -C "$(dirname "$MANBA")" "$(basename "$MANBA")"
echo "Saqlandi: $FAYL ($(du -h "$FAYL" | cut -f1))"
chmod +x zaxira.sh && ./zaxira.sh
tar -tzf zaxiralar/sayt_*.tar.gz | head
-C "$(dirname ...)" — arxivda absolyut yo'llar emas, sayt/... bo'lishi uchun (31-dars).
2-mashq: Argumentlar va tekshiruvlar
Skriptni yaxshilang:
- 1-argument — manba papka (majburiy), 2-argument — saqlash kunlari (standart 7)
- Argument berilmasa — foydalanish yo'riqnomasi
- Manba papka mavjud bo'lmasa — xato
- Kunlar soni raqam bo'lmasa — xato
- Arxiv bo'sh yoki buzilgan bo'lsa — xato (
tar -tzfbilan tekshirish)
Yechim
#!/usr/bin/env bash
set -euo pipefail
xato() { echo "XATO: $*" >&2; exit 1; }
[[ $# -lt 1 ]] && { echo "Foydalanish: $0 <papka> [kunlar=7]"; exit 1; }
MANBA="$(realpath "$1")"
KUNLAR="${2:-7}"
MANZIL="$HOME/mashq-skript/zaxiralar"
[[ -d "$MANBA" ]] || xato "Papka topilmadi: $MANBA"
[[ "$KUNLAR" =~ ^[0-9]+$ ]] || xato "Kunlar raqam bo'lishi kerak: $KUNLAR"
NOM="$(basename "$MANBA")"
FAYL="$MANZIL/${NOM}_$(date +%F_%H%M%S).tar.gz"
mkdir -p "$MANZIL"
tar -czf "$FAYL" -C "$(dirname "$MANBA")" "$NOM"
tar -tzf "$FAYL" > /dev/null || xato "Arxiv buzilgan: $FAYL"
[[ -s "$FAYL" ]] || xato "Arxiv bo'sh: $FAYL"
echo "Saqlandi: $FAYL ($(du -h "$FAYL" | cut -f1))"
./zaxira.sh # yo'riqnoma
./zaxira.sh yoq-papka # XATO: Papka topilmadi
./zaxira.sh sayt abc # XATO: Kunlar raqam bo'lishi kerak
./zaxira.sh sayt 14 # ✓
realpath — nisbiy yo'lni absolyutga aylantiradi.
3-mashq: Rotatsiya va log
Qo'shing:
KUNLARdan eski zaxiralarni o'chirish (nechtasi o'chirilganini chiqarish)- Har bir xabar — vaqt bilan, ham ekranga, ham
zaxira.logga (logfunksiyasi) - Xato bo'lganda — qaysi qatorda ekanini log ga yozish (
trap ERR)
Sinash uchun eski fayllar yarating: touch -d "10 days ago" zaxiralar/sayt_eski{1,2,3}.tar.gz
Yechim
#!/usr/bin/env bash
set -euo pipefail
readonly MANZIL="$HOME/mashq-skript/zaxiralar"
readonly LOG="$HOME/mashq-skript/zaxira.log"
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
xato() { log "XATO: $*"; exit 1; }
trap 'log "XATO: $LINENO-qatorda: $BASH_COMMAND"' ERR
[[ $# -lt 1 ]] && { echo "Foydalanish: $0 <papka> [kunlar=7]"; exit 1; }
readonly MANBA="$(realpath "$1")"
readonly KUNLAR="${2:-7}"
[[ -d "$MANBA" ]] || xato "Papka topilmadi: $MANBA"
[[ "$KUNLAR" =~ ^[0-9]+$ ]] || xato "Kunlar raqam bo'lishi kerak"
main() {
local nom fayl ochirildi
nom="$(basename "$MANBA")"
fayl="$MANZIL/${nom}_$(date +%F_%H%M%S).tar.gz"
log "Boshlandi: $MANBA"
mkdir -p "$MANZIL"
tar -czf "$fayl" -C "$(dirname "$MANBA")" "$nom"
tar -tzf "$fayl" > /dev/null || xato "Arxiv buzilgan"
log "Saqlandi: $fayl ($(du -h "$fayl" | cut -f1))"
ochirildi=$(find "$MANZIL" -name "${nom}_*.tar.gz" -mtime +"$KUNLAR" -print -delete | wc -l)
log "Eski zaxiralar o'chirildi: $ochirildi ta (>$KUNLAR kun)"
log "Jami zaxiralar: $(find "$MANZIL" -name "${nom}_*.tar.gz" | wc -l) ta, $(du -sh "$MANZIL" | cut -f1)"
}
main
touch -d "10 days ago" zaxiralar/sayt_eski{1,2,3}.tar.gz
./zaxira.sh sayt 7
cat zaxira.log
[2026-11-06 15:02:11] Boshlandi: /home/otabek/mashq-skript/sayt
[2026-11-06 15:02:11] Saqlandi: .../sayt_2026-11-06_150211.tar.gz (1.1M)
[2026-11-06 15:02:11] Eski zaxiralar o'chirildi: 3 ta (>7 kun)
[2026-11-06 15:02:11] Jami zaxiralar: 2 ta, 2.1M
4-mashq: Sog'liq tekshiruvi
tekshir.sh skriptini yozing. U tekshiradi:
- URL javob beradimi (
curl -sf, 5 soniya timeout) — URL argument sifatida - Disk ildizi 85% dan oshmaganmi
- Mavjud xotira (
available) 200 MB dan kammi
Har bir muammo — ro'yxatga yig'iladi. Oxirida: muammo bo'lmasa — ✓ Hammasi joyida (chiqish kodi 0), bo'lsa — barcha muammolar ro'yxati (chiqish kodi 1).
Yechim
#!/usr/bin/env bash
set -euo pipefail
URL="${1:-http://localhost:3000/health}"
DISK_CHEGARA=85
XOTIRA_MIN_MB=200
MUAMMOLAR=()
# 1. Sayt
if ! curl -sf --max-time 5 "$URL" > /dev/null; then
MUAMMOLAR+=("Sayt javob bermayapti: $URL")
fi
# 2. Disk
DISK=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if (( DISK >= DISK_CHEGARA )); then
MUAMMOLAR+=("Disk ${DISK}% to'la (chegara ${DISK_CHEGARA}%)")
fi
# 3. Xotira
XOTIRA=$(free -m | awk '/^Mem:/ {print $7}')
if (( XOTIRA < XOTIRA_MIN_MB )); then
MUAMMOLAR+=("Mavjud xotira kam: ${XOTIRA} MB")
fi
# Natija
if (( ${#MUAMMOLAR[@]} == 0 )); then
echo "✓ Hammasi joyida (disk ${DISK}%, xotira ${XOTIRA} MB)"
exit 0
fi
echo "⚠️ $(hostname): ${#MUAMMOLAR[@]} ta muammo"
for M in "${MUAMMOLAR[@]}"; do
echo " - $M"
done
exit 1
chmod +x tekshir.sh
./tekshir.sh https://google.com
./tekshir.sh http://localhost:9999 # muammo bilan
echo $? # 1
MUAMMOLAR=()— bo'sh massiv;+=("...")— qo'shish;${#MUAMMOLAR[@]}— elementlar soniif ! curl ...—!buyruq natijasini inkor qiladi;set -ehamifichida ishlamaydi
5-mashq: Telegram ga xabar
Muammo bo'lganda xabarni Telegram ga yuboring.
Tayyorlash: Telegram da @BotFather → /newbot → token oling. Botga biror xabar yozing, keyin chat ID ni bilib oling:
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates" | jq '.result[0].message.chat.id'
xabar_yubor funksiyasini yozing va tekshir.sh ga qo'shing. Token va chat ID — muhit o'zgaruvchilaridan (TG_TOKEN, TG_CHAT), skriptda yozilmasin.
Yechim
tekshir.sh boshiga:
: "${TG_TOKEN:?TG_TOKEN o'rnatilmagan}"
: "${TG_CHAT:?TG_CHAT o'rnatilmagan}"
xabar_yubor() {
curl -sf --max-time 10 \
"https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-d chat_id="$TG_CHAT" \
--data-urlencode text="$1" > /dev/null
}
Natija qismini o'zgartiring:
MATN="⚠️ $(hostname): ${#MUAMMOLAR[@]} ta muammo"
for M in "${MUAMMOLAR[@]}"; do
MATN+=#39;\n'"- $M"
done
echo "$MATN"
xabar_yubor "$MATN" || echo "Telegram ga yuborib bo'lmadi" >&2
exit 1
Maxfiy ma'lumotlar — alohida faylda:
cat > ~/.tekshir.env << 'EOF'
TG_TOKEN=123456:ABC-...
TG_CHAT=987654321
EOF
chmod 600 ~/.tekshir.env
set -a; source ~/.tekshir.env; set +a
./tekshir.sh http://localhost:9999
--data-urlencode— maxsus belgilar va yangi qatorlarni to'g'ri yuborish#39;\n'— haqiqiy yangi qator belgisi
6-mashq: Rejalashtirish
- Zaxira — har kecha 02:30 da (cron)
- Tekshiruv — har 5 daqiqada (cron),
.tekshir.envni yuklab - Har ikkalasining chiqishi — log fayllarga
- Ishlayotganini tekshiring
Yechim
crontab -e
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
30 2 * * * $HOME/mashq-skript/zaxira.sh $HOME/mashq-skript/sayt 14 >> $HOME/mashq-skript/cron-zaxira.log 2>&1
*/5 * * * * set -a; . $HOME/.tekshir.env; set +a; $HOME/mashq-skript/tekshir.sh https://google.com >> $HOME/mashq-skript/cron-tekshir.log 2>&1
crontab -l
# 5 daqiqa kuting...
tail ~/mashq-skript/cron-tekshir.log
grep CRON /var/log/syslog | tail -3
Production da tekshiruv uchun systemd timer (40-dars) yaxshiroq — EnvironmentFile= bilan .env yuklash ancha toza.
Tozalash: crontab -e da qatorlarni o'chiring yoki crontab -r (barcha vazifalar!), rm -rf ~/mashq-skript ~/.tekshir.env.
Nima uchun shunday?
Nima uchun tekshiruv skripti barcha muammolarni yig'ib, keyin bitta xabar yuboradi — har biri uchun alohida emas?
Chunki ogohlantirish tizimining eng katta dushmani — shovqin. Har 5 daqiqada uchta alohida xabar kelsa — bir kunda yuzlab; odam ularni o'qishni to'xtatadi va haqiqiy muammo e'tibordan chetda qoladi ("alert fatigue"). Bitta xabar, barcha muammolar bilan, server nomi bilan — darhol manzarani beradi. Keyingi qadam (o'zingiz qo'shib ko'ring): bir xil muammo uchun har 5 daqiqada emas, faqat holat o'zgarganda xabar yuborish — "muammo paydo bo'ldi" va "muammo hal bo'ldi". Haqiqiy monitoring tizimlari (Grafana, Uptime Kuma) aynan shunday ishlaydi.
Xulosa
Siz yozdingiz:
- Arxivlash + tekshirish + rotatsiya bilan zaxira skripti
log,xatofunksiyalari,trap ERR,readonly,main- Argumentlarni tekshirish:
[[ -d ]],=~ ^[0-9]+$ - Massivlar:
MUAMMOLAR+=(),${#MUAMMOLAR[@]} curlbilan sayt tekshiruvi va Telegram API- Sirlar —
chmod 600fayl va${VAR:?} - cron da:
SHELL,PATH, absolyut yo'llar, log ga yo'naltirish
Keyingi bo'lim
9-bo'lim: Server — yangi VPS ni sozlash, Nginx va yakuniy loyiha.