Skip to content

8. Bash skriptlash — 40 ta masala

Skriptlarni ~/lab ichida yozing. Har bir skriptni ishga tushirishdan oldin chmod +x qilishni unutmang:

mkdir -p ~/lab && cd ~/lab

Asoslar

1. hello.sh skripti "Salom, dunyo" chiqarsin va to'g'ri shebang bilan bajariladigan bo'lsin.
Misol: ./hello.sh → Salom, dunyo

Yechim

cat > hello.sh <<'EOF'
#!/usr/bin/env bash
echo "Salom, dunyo"
EOF
chmod +x hello.sh
./hello.sh
Birinchi qator (#!) yadroga skriptni qaysi interpretator bilan ishga tushirishni aytadi.

2. O'zgaruvchiga ism yozing va uni qo'shtirnoq ichida chiqaring. '...' va "..." farqini ko'rsating.
Misol: Salom, Ali va Salom, $ISM.

Yechim

ISM="Ali"
echo "Salom, $ISM"
echo 'Salom, $ISM'
Ikkitalik qo'shtirnoqda o'zgaruvchilar almashtiriladi, bittalikda matn o'zgarishsiz qoladi. = atrofida bo'shliq bo'lmasligi kerak (ISM = "Ali" xato).

3. Skriptga berilgan birinchi argument va argumentlar sonini chiqaring.
Misol: ./args.sh a b c → birinchi: a, jami: 3

Yechim
cat > args.sh <<'EOF'
#!/usr/bin/env bash
echo "birinchi: $1, jami: $#"
EOF
chmod +x args.sh
./args.sh a b c

4. Argumentlar ichida bo'shliq bo'lsa ham ular to'g'ri bo'linishi uchun "$@" va $* farqini ko'rsating.
Misol: ./loop.sh "a b" c → ikki element: a b va c.

Yechim

cat > loop.sh <<'EOF'
#!/usr/bin/env bash
for x in "$@"; do echo "[$x]"; done
EOF
chmod +x loop.sh
./loop.sh "a b" c
"$@" har bir argumentni alohida saqlaydi, $* (qo'shtirnoqsiz) bo'shliq bo'yicha qayta bo'lib yuboradi.

5. Foydalanuvchidan ism so'rang va uni chiqaring.
Misol: Ismingiz: Ali → Xush kelibsiz, Ali

Yechim

read -rp "Ismingiz: " ISM
echo "Xush kelibsiz, $ISM"
-r teskari chiziqni (\) maxsus belgi deb talqin qilmaydi, -p so'rov matni.

6. Fayl mavjudligini tekshiring.
Misol: /etc/passwd → bor.

Yechim

if [ -f /etc/passwd ]; then echo "bor"; else echo "yo'q"; fi
-f — oddiy fayl, -d — katalog, -e — har qanday yo'l, -r/-w/-x — o'qish/yozish/bajarish huquqi. [ va ] atrofida bo'shliq shart.

7. Katalog mavjud bo'lmasa, uni yarating.
Misol: [ -d out ] || mkdir out.

Yechim

[ -d out ] || mkdir out
Yoki shunchaki mkdir -p out: mavjud bo'lsa xato bermaydi.

8. Ikki sonni solishtiring, so'ng ikki matnni solishtiring. Nega -gt va > boshqa-boshqa?
Misol: [ 10 -gt 9 ] rost.

Yechim

[ 10 -gt 9 ] && echo "10 > 9"
[ "10" \> "9" ] || echo "matn sifatida 10 < 9"
Sonlar uchun -eq -ne -gt -lt -ge -le, matn uchun = != < >. [ ] ichida > ni \> bilan yozish kerak (aks holda redirect bo'lib qoladi); [[ ]] da qochirish shart emas.

9. [[ ]] yordamida satr regex'ga mosligini tekshiring.
Misol: 192.168.1.10 IP ko'rinishidami?

Yechim

IP="192.168.1.10"
if [[ $IP =~ ^[0-9]+(\.[0-9]+){3}$ ]]; then echo "IP"; fi
[[ ]] — bash'ga xos, kengaytmalarni bo'laklamaydi va =~ ni qo'llaydi. POSIX sh da ishlamaydi.

Sikl va shartlar

10. ~/lab dagi har bir .log faylining qatorlar sonini chiqaring.
Misol: a.log: 12

Yechim

for f in ~/lab/*.log; do
    [ -e "$f" ] || continue
    echo "$f: $(wc -l < "$f")"
done
Mos fayl bo'lmasa, *.log o'zi matn sifatida qoladi; [ -e ] tekshiruvi bu holatni o'tkazib yuboradi. Qo'shtirnoq fayl nomidagi bo'shliqlardan himoya qiladi.

11. 1 dan 5 gacha sonlarni chiqaring (ikki usulda).
Misol: 1 2 3 4 5.

Yechim

for i in {1..5}; do echo "$i"; done
for i in $(seq 1 5); do echo "$i"; done
{1..5} ichiga o'zgaruvchi qo'yib bo'lmaydi ({1..$N} ishlamaydi); u holda seq 1 "$N".

12. Faylni qatorma-qator o'qing va har bir qatorni raqam bilan chiqaring.
Misol: 1: birinchi qator.

Yechim

n=0
while IFS= read -r line; do
    n=$((n+1))
    echo "$n: $line"
done < /etc/hostname
IFS= va -r qatorning bosh/oxiridagi bo'shliqlarni va \ belgilarini saqlaydi.

13. case yordamida start|stop|status argumentlarini ishlang, boshqa qiymatda yordam chiqaring.
Misol: ./svc.sh foo → Usage: ....

Yechim
case "$1" in
    start)  echo "ishga tushdi" ;;
    stop)   echo "to'xtadi" ;;
    status) echo "ishlayapti" ;;
    *)      echo "Usage: $0 {start|stop|status}" >&2; exit 1 ;;
esac

14. Ikki sonni qo'shadigan funksiya yozing va natijani o'zgaruvchiga oling.
Misol: qosh 3 4 → 7.

Yechim

qosh() { echo $(( $1 + $2 )); }
natija=$(qosh 3 4)
echo "$natija"
Bash funksiyasining return qiymati faqat 0–255 chiqish kodi; haqiqiy qiymatni echo bilan qaytarib, $(...) bilan olinadi.

15. Oxirgi buyruqning chiqish kodini tekshiring. grep topmasa nima qaytaradi?
Misol: grep yoq /etc/hostname; echo $? → 1.

Yechim

grep -q root /etc/passwd; echo $?
grep -q yoq-bunday /etc/passwd; echo $?
0 — muvaffaqiyat, nolga teng bo'lmagan qiymat — xato (grep uchun 1 — topilmadi, 2 — xatolik). -q — hech narsa chiqarmaydi, faqat kod beradi.

16. Skript boshida set -euo pipefail yozilsa, har bir bayroq nimani o'zgartiradi?
Misol: xato buyruq skriptni to'xtatadi.

Yechim

#!/usr/bin/env bash
set -euo pipefail
echo "boshladik"
false
echo "bu chiqmaydi"
-e — buyruq xato bilan tugasa, skript to'xtaydi; -u — aniqlanmagan o'zgaruvchi xato; -o pipefail — pipe ichidagi istalgan buyruq xatosi butun pipe xatosi bo'ladi (aks holda faqat oxirgisi hisobga olinadi).

17. Vaqtinchalik fayl yarating va skript qanday tugashidan qat'i nazar uni tozalang.
Misol: Ctrl+C bosilsa ham fayl o'chadi.

Yechim

TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT
echo "ish" > "$TMP"
sleep 5
trap ... EXIT normal chiqish, xato va Ctrl+C da ham ishlaydi. mktemp bashorat qilib bo'lmaydigan nom beradi (/tmp/test.txt kabi qat'iy nom xavfsiz emas).

18. Bugungi sana bilan fayl nomini yasang.
Misol: backup-2026-10-12.tar.gz

Yechim

FILE="backup-$(date +%F).tar.gz"
echo "$FILE"
$(...) — buyruq natijasini qiymatga aylantiradi (eski `...` shakli o'rniga).

19. Arifmetika: ikki o'zgaruvchining yig'indisi va butun bo'linmasi.
Misol: a=17 b=5 → 22, 3.

Yechim

a=17; b=5
echo $((a + b)) $((a / b))
Bash faqat butun sonlar bilan ishlaydi. Kasr uchun bc yoki awk.

20. O'zgaruvchi berilmagan bo'lsa, standart qiymat bering.
Misol: PORT yo'q bo'lsa 8080.

Yechim

PORT="${PORT:-8080}"
echo "port: $PORT"
${VAR:-x} — VAR bo'sh yoki aniqlanmagan bo'lsa x. ${VAR:?xabar} — bo'sh bo'lsa xabar bilan to'xtatadi.

21. Skript root huquqisiz ishga tushirilsa, to'xtasin.
Misol: Root sifatida ishga tushiring.

Yechim

if [ "$EUID" -ne 0 ]; then
    echo "Root sifatida ishga tushiring" >&2
    exit 1
fi
Xato xabari stderr ga (>&2) yoziladi.

22. Skript kerakli dasturlar o'rnatilganini tekshirsin.
Misol: curl yo'q bo'lsa to'xtaydi.

Yechim
for cmd in curl jq tar; do
    command -v "$cmd" >/dev/null 2>&1 || { echo "$cmd topilmadi" >&2; exit 1; }
done

23. Massiv yarating, elementlarini chiqaring va uzunligini toping.
Misol: 3.

Yechim
SERVERS=(web1 web2 db1)
echo "${#SERVERS[@]}"
for s in "${SERVERS[@]}"; do echo "$s"; done

24. Fayl nomidan kengaytmani va katalog qismini ajrating.
Misol: /var/log/app.log → /var/log/app, app.log.

Yechim

P=/var/log/app.log
echo "${P%.log}"
echo "${P##*/}"
basename "$P"; dirname "$P"
% — oxiridan, # — boshidan olib tashlaydi (%%/## — eng uzun moslik).

25. Ko'p qatorli matnni faylga here-document bilan yozing.
Misol: cat conf.txt ikki qator chiqaradi.

Yechim

cat > conf.txt <<EOF
host=$(hostname)
port=8080
EOF
<<'EOF' (qo'shtirnoqda) bo'lsa, $(hostname) almashtirilmaydi, matn o'zgarishsiz yoziladi.

26. && va || bilan: katalog yarating va unga kiring; bajarilmasa xabar chiqaring.
Misol: mkdir d && cd d || echo xato.

Yechim

mkdir -p d && cd d || { echo "xato" >&2; exit 1; }
Skriptda cd xato bersa, davom etish xavfli: keyingi rm * boshqa katalogda ishlab ketishi mumkin.

27. Nega rm $FILE fayl nomida bo'shliq bo'lsa xavfli? To'g'ri yozing.
Misol: FILE="my report.txt".

Yechim

FILE="my report.txt"
rm -- "$FILE"
Qo'shtirnoqsiz $FILE ikki argumentga (my va report.txt) bo'linadi va noto'g'ri fayllar o'chadi. Har doim "$VAR". -- nomi - bilan boshlanadigan fayllardan himoya qiladi.

28. Skriptingizni shellcheck bilan tekshiring.
Misol: SC2086: Double quote to prevent globbing and word splitting.

Yechim

sudo apt install -y shellcheck
shellcheck hello.sh args.sh
Bu xatolarning ko'pi aynan qo'shtirnoqsiz o'zgaruvchilar bilan bog'liq. CI jarayoniga qo'shish foydali.

29. Skriptni qadamma-qadam kuzatib nosozlikni toping.
Misol: har bir buyruq + belgisi bilan chiqadi.

Yechim

bash -x ./hello.sh
Skript ichida bir qismni kuzatish: set -x ... set +x.

Amaliy skriptlar

30. Veb-sahifa 200 qaytarsa 0, aks holda 1 bilan chiqadigan healthcheck yozing.
Misol: ./check.sh https://example.com; echo $?

Yechim

#!/usr/bin/env bash
URL="${1:?URL kerak}"
CODE=$(curl -o /dev/null -s -m 5 -w '%{http_code}' "$URL")
if [ "$CODE" = "200" ]; then
    echo "OK ($CODE)"
    exit 0
fi
echo "XATO ($CODE)" >&2
exit 1
-m 5 — 5 soniyadan keyin tark etadi, aks holda skript muzlab qolishi mumkin. Chiqish kodi monitoring va cron uchun asosiy signal.

31. ~/lab/proj ning sana bilan nomlangan zaxira arxivini ~/backups ga yaratuvchi skript yozing.
Misol: ~/backups/proj-2026-10-12.tar.gz

Yechim
#!/usr/bin/env bash
set -euo pipefail
SRC="$HOME/lab/proj"
DEST="$HOME/backups"
mkdir -p "$DEST"
tar -czf "$DEST/proj-$(date +%F).tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
echo "zaxira tayyor"

32. ~/backups dagi 7 kundan eski arxivlarni o'chiruvchi skript yozing; avval nimani o'chirishini ko'rsatsin.
Misol: -print ro'yxati, so'ng -delete.

Yechim
#!/usr/bin/env bash
DIR="$HOME/backups"
find "$DIR" -name '*.tar.gz' -type f -mtime +7 -print
find "$DIR" -name '*.tar.gz' -type f -mtime +7 -delete

Ehtiyot bo'ling

DIR bo'sh qolsa, find "" ... ham, find / ... ham xavfli bo'lishi mumkin. O'zgaruvchini DIR="${DIR:?}" bilan majburiy qiling va birinchi marta faqat -print bilan sinang.

33. / bo'limi 80% dan ko'p band bo'lsa ogohlantiradigan skript yozing.
Misol: OGOHLANTIRISH: / 85% band

Yechim

#!/usr/bin/env bash
USED=$(df --output=pcent / | tail -n 1 | tr -dc '0-9')
if [ "$USED" -ge 80 ]; then
    echo "OGOHLANTIRISH: / ${USED}% band" >&2
    exit 1
fi
tr -dc '0-9' — % va bo'shliqlarni olib tashlab, faqat raqamlarni qoldiradi.

34. Katalogdagi har bir .txt fayl nomini va qatorlar sonini fayl,qator CSV ko'rinishida chiqaring.
Misol: a.txt,12.

Yechim
for f in *.txt; do
    [ -e "$f" ] || continue
    printf '%s,%s\n' "$f" "$(wc -l < "$f")"
done

35. Skriptning ikki nusxasi bir vaqtda ishlamasligini ta'minlang.
Misol: ikkinchi ishga tushirish Allaqachon ishlayapti deydi.

Yechim

#!/usr/bin/env bash
exec 9>/var/lock/myjob.lock
flock -n 9 || { echo "Allaqachon ishlayapti" >&2; exit 1; }
sleep 30
flock fayl qulfini jarayon tugaganda avtomatik bo'shatadi; qulf-faylni qo'lda yaratib o'chirish usulida skript yiqilsa, "osilib qolgan" qulf qoladi.

36. -v va -o fayl opsiyalarini qabul qiladigan skript yozing.
Misol: ./run.sh -v -o out.txt.

Yechim

VERBOSE=0; OUT=""
while getopts "vo:" opt; do
    case $opt in
        v) VERBOSE=1 ;;
        o) OUT=$OPTARG ;;
        *) echo "Usage: $0 [-v] [-o fayl]" >&2; exit 1 ;;
    esac
done
echo "verbose=$VERBOSE out=$OUT"
o: dagi : — bu opsiya qiymat talab qilishini bildiradi.

37. Skript xabarini tizim jurnaliga yozing va topib ko'ring.
Misol: journalctl -t mybackup.

Yechim

logger -t mybackup "zaxira tugadi"
journalctl -t mybackup -n 3
Cron yoki xizmat sifatida ishlaganda ekran yo'q, shuning uchun natijani logger bilan jurnalga yozish qulay.

38. CSV qatorini vergul bo'yicha maydonlarga ajrating.
Misol: ali,25,Toshkent → ali 25 Toshkent.

Yechim
echo "ali,25,Toshkent" | while IFS=, read -r ism yosh shahar; do
    echo "$ism $yosh $shahar"
done

39. Buyruqni 3 martagacha qayta urinadigan retry funksiyasini yozing.
Misol: barqaror bo'lmagan tarmoq so'rovi uchun.

Yechim

retry() {
    local n=1
    until "$@"; do
        if [ "$n" -ge 3 ]; then echo "$n urinishdan keyin xato" >&2; return 1; fi
        n=$((n+1)); sleep 2
    done
}
retry curl -fsS https://example.com -o /dev/null
curl -f HTTP 4xx/5xx da ham nolga teng bo'lmagan kod qaytaradi, aks holda retry xatoni payqamaydi.

40. Skript terminalda ishlaydi, lekin cron'da yiqiladi. Eng ko'p uchraydigan sababni va tuzatishni ayting.
Misol: cron'da command not found.

Yechim

#!/usr/bin/env bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cd /opt/app || exit 1
/usr/bin/python3 /opt/app/job.py >> /var/log/job.log 2>&1
Cron minimal PATH (/usr/bin:/bin) bilan ishlaydi va sizning ~/.bashrc ni o'qimaydi. Skriptda PATH ni o'rnating, dasturlarning to'liq yo'lini yozing, joriy katalogga tayanmang va chiqishni faylga yo'naltiring.