Bash skript asoslari — shebang, o'zgaruvchilar, qo'shtirnoq

~15 daq · Linux · Bash skriptlar

Muammodan boshlaylik

Har bir deploy da bir xil buyruqlar:

cd /opt/dokon
git pull
npm ci
npm run build
sudo systemctl restart dokon
curl -sf localhost:3000/health

Har safar qo'lda — 6 qadam, birini unutish yoki noto'g'ri tartibda bajarish oson. Bular skriptga aylanishi kerak: bitta fayl, bitta buyruq, har safar bir xil natija.

Bash skript — shunchaki terminalda yozadigan buyruqlaringiz, faylga yozilgan. Siz allaqachon 90% ini bilasiz.


Birinchi skript

nano salom.sh
#!/bin/bash
# Mening birinchi skriptim
echo "Salom, $USER!"
echo "Bugun: $(date +%F)"
echo "Siz $(pwd) papkasidasiz"

Ishga tushirish:

chmod +x salom.sh       # ishga tushirish huquqi (20-dars)
./salom.sh
Salom, otabek!
Bugun: 2026-11-06
Siz /home/otabek papkasidasiz

Yoki chmod siz: bash salom.sh.

Shebang

Birinchi qator #!/bin/bash — shebang: tizimga "bu faylni bash bilan ishga tushir" deydi. Busiz fayl qaysi interpretator bilan bajarilishi noaniq.

#!/bin/bash           # bash
#!/usr/bin/env bash   # PATH dagi bash (ko'chiriladigan — macOS va boshqalar)
#!/bin/sh             # POSIX shell — minimal, Alpine/Docker da
#!/usr/bin/env python3
#!/usr/bin/env node

# bilan boshlangan boshqa qatorlar — izoh.

[!WARNING] Windows da yozilgan skript: /bin/bash^M: bad interpreter. Sabab — Windows qator oxirlari (\r\n). Tuzatish: sed -i 's/\r$//' skript.sh (8-dars). VS Code da pastki o'ng burchakda CRLF → LF.


O'zgaruvchilar

#!/bin/bash
ISM="Otabek"
YOSH=25
PAPKA="/opt/dokon"

echo "Ism: $ISM"
echo "Yosh: ${YOSH}"
echo "Zaxira: ${PAPKA}_zaxira"
  • = atrofida bo'shliq yo'q (30-dars)
  • $ISM yoki ${ISM} — qiymatni olish
  • ${} — nom chegarasi noaniq bo'lganda: ${PAPKA}_zaxira ($PAPKA_zaxira — PAPKA_zaxira nomli o'zgaruvchi deb o'qiladi)
  • Odatda: o'zgaruvchilar — KATTA_HARF (muhit o'zgaruvchilari) yoki kichik_harf (skript ichidagi)

Buyruq natijasi

SANA=$(date +%F)
FAYLLAR=$(ls | wc -l)
VERSIYA=$(git rev-parse --short HEAD)
echo "Sana: $SANA, fayllar: $FAYLLAR, versiya: $VERSIYA"

Arifmetika

A=10
B=3
echo $(( A + B ))       # 13
echo $(( A * B ))       # 30
echo $(( A / B ))       # 3 — faqat butun sonlar!
echo $(( A % B ))       # 1
(( A++ ))
echo $A                 # 11

Kasr sonlar kerak bo'lsa — awk yoki bc: echo "10 / 3" | bc -l.

Standart qiymatlar

PORT=${PORT:-3000}             # PORT bo'sh bo'lsa — 3000
MUHIT=${1:-development}        # birinchi argument yoki "development"
: "${DB_PAROL:?DB_PAROL o'rnatilmagan}"    # bo'sh bo'lsa — xato bilan to'xtash

${VAR:?xabar} — muhim o'zgaruvchilar uchun himoya (7-darsdagi rm -rf "$PAPKA/" falokati esingizdami?).


Qo'shtirnoqlar — eng muhim mavzu

Bash dagi xatolarning katta qismi qo'shtirnoqlardan.

Yozuv O'zgaruvchilar Misol Natija
"..." (qo'sh) ✅ Almashtiriladi "Salom $ISM" Salom Otabek
'...' (yakka) ❌ Aynan shunday 'Salom $ISM' Salom $ISM
Qo'shtirnoqsiz ✅ + bo'linadi Xavfli

Nima uchun doim "$VAR"

FAYL="Mening hujjatim.txt"
touch "$FAYL"

rm $FAYL          # ❌ rm "Mening" "hujjatim.txt" — ikki fayl!
rm "$FAYL"        # ✅

Qo'shtirnoqsiz o'zgaruvchi bo'shliqlar bo'yicha bo'linadi va glob (*) lar kengaytiriladi. Qoida:

[!TIP] O'zgaruvchilarni har doim qo'sh qo'shtirnoqqa oling: "$VAR", "$(buyruq)", "${PAPKA}/fayl". Istisno — aniq bo'linish kerak bo'lgan kamdan-kam holatlar.

Yakka qo'shtirnoq — aynan matn

echo 'Narx: $100'                       # Narx: $100
awk '{print $1}' fayl.txt               # $1 — awk uchun, bash uchun emas
ssh server 'echo $HOME'                 # serverdagi $HOME
ssh server "echo $HOME"                 # lokal $HOME (lokal almashtiriladi!)

Foydalanuvchi bilan ishlash

Chiqarish

echo "Oddiy matn"
echo -e "Qator 1\nQator 2\tTab"         # -e — \n, \t ni tushunish
printf "%-10s %5d\n" "Olma" 42           # formatlangan

Ranglar:

QIZIL='\033[0;31m'
YASHIL='\033[0;32m'
YOQ='\033[0m'
echo -e "${YASHIL}✓ Muvaffaqiyatli${YOQ}"
echo -e "${QIZIL}✗ Xato${YOQ}"

Kiritish

read -p "Ismingiz: " ISM
echo "Salom, $ISM!"

read -sp "Parol: " PAROL           # -s — ekranda ko'rinmaydi
echo

read -p "Davom etaymi? (h/y) " JAVOB

Argumentlar

./deploy.sh production v1.4.2
O'zgaruvchi Qiymat
$0 Skript nomi (./deploy.sh)
$1, $2, ... Argumentlar (production, v1.4.2)
$# Argumentlar soni (2)
$@ Barcha argumentlar (alohida-alohida)
$? Oxirgi buyruqning chiqish kodi
$ Skript PID i
#!/bin/bash
MUHIT="$1"
VERSIYA="${2:-latest}"
echo "$MUHIT muhitiga $VERSIYA versiyasi deploy qilinmoqda..."
echo "Jami $# ta argument: $@"

Amaliy skript: deploy

#!/bin/bash
# deploy.sh — dokon ilovasini yangilash

PAPKA="/opt/dokon"
SANA=$(date '+%F %T')

echo "[$SANA] Deploy boshlandi"

cd "$PAPKA" || exit 1
git pull
npm ci
npm run build
sudo systemctl restart dokon
sleep 2

if curl -sf localhost:3000/health > /dev/null; then
  echo "✓ Ilova ishlayapti"
else
  echo "✗ Ilova javob bermayapti!"
  exit 1
fi

cd ... || exit 1 — papkaga o'tib bo'lmasa, to'xtash (aks holda keyingi buyruqlar noto'g'ri papkada bajariladi). Lekin agar npm ci xato bersa-chi? Skript davom etadi. Buni 39-darsda set -e bilan hal qilamiz. if — keyingi darsda.


Nima uchun shunday?

Nima uchun bash — 1989 yildagi til — hali ham avtomatlashtirishning standarti, Python bor bo'lsa ham?

Chunki bash — buyruqlarni birlashtirish uchun yaratilgan va bu ishda unga teng keladigani yo'q. Python da git pull ni chaqirish — subprocess.run(["git", "pull"], check=True); bash da — shunchaki git pull. Pipe, yo'naltirish, fon jarayonlar — hammasi tilning o'zida. Va eng muhimi — bash har bir Linux serverda, har bir Docker image da (yoki sh), har bir CI runner da allaqachon bor. Qoida: buyruqlarni ketma-ket ishga tushirish va oddiy mantiq — bash; murakkab ma'lumotlar tuzilmalari, JSON, matematika, 100+ qator — Python.


Xulosa

Eslab qoling:

  • #!/bin/bash — birinchi qator; chmod +x; ./skript.sh
  • VAR="qiymat" — bo'shliqsiz; $VAR, ${VAR}
  • $(buyruq) — natija; $(( a + b )) — arifmetika
  • ${VAR:-standart}, ${VAR:?xato}
  • Doim "$VAR" — qo'sh qo'shtirnoqda; '...' — aynan matn
  • read -p — kiritish; echo -e — maxsus belgilar
  • $1, $2, $#, $@ — argumentlar
  • cd papka || exit 1
  • Windows \r — sed -i 's/\r$//'

Keyingi dars

38-dars: Shartlar va tsikllar — if, test, for, while, case