Tarkibga o'tish

Bash skript asoslari

"13. Disk, filesystem, LVM va storage" modulida Disk to'lganda troubleshooting maqolasida bitta muhim kuzatuv qilingan edi: df -h → df -i → du → lsof ketma-ketligi aniq, tartibli tekshiruv bo'lib, uni har safar qo'lda takrorlashga to'g'ri kelardi. Qo'lda bir necha martadan ko'p takrorlanadigan har qanday vazifa — tekshiruv, backup yoki tozalash — avtomatlashtirish uchun tabiiy nomzod. Bash scripting aynan shu avtomatlashtirish vositasi. Bu maqola "14. Bash scripting" modulini ochadi: avval skript nima ekani, uning tuzilishi va qanday ishga tushirilishi ko'rib chiqiladi. Keyingi maqolalarda o'zgaruvchilar, shartlar, sikllar, funksiyalar va xatolarni qayta ishlash qo'shiladi, modul esa uchta to'liq, ishlaydigan production skript bilan yakunlanadi.

Nimalarni o'rganasiz

Bu maqola oxirida siz quyidagilarni qila olasiz:

  • skript nima ekanini va uni nega yozishga arzishini tushuntirish;
  • shebang qatori nima uchun kerakligini va uni qanday tanlashni tushuntirish;
  • skriptga execute ruxsatini berish va uni ikki xil usulda ishga tushirish;
  • izoh (comment) yozish qoidalariga amal qilish;
  • skriptni shellcheck bilan tekshirishni boshlash.

Skript nima va u nega kerak

Skript — matnli faylga yozilgan va ketma-ket bajariladigan buyruqlar to'plami. Terminalga bittadan yoziladigan har qanday buyruqni skript ichiga joylash mumkin. Farqi shundaki, skript bir marta yoziladi, keyin esa istalgancha, aynan bir xil tartibda va xatosiz qayta ishga tushiriladi. Skriptni interpreter bajaradi — bu buyruqlarni birma-bir o'qib, tizimga uzatadigan dastur. Bash skriptlari uchun interpreter bash dasturining o'zi.

Skript quyidagi vaziyatlarda o'zini oqlaydi:

  • bir xil buyruqlar ketma-ketligi muntazam (har kuni, har hafta) bajarilishi kerak;
  • buyruq qatori shunchalik uzunki, uni qo'lda qayta yozish xatoga olib keladi;
  • vazifa cron yoki systemd timer orqali inson ishtirokisiz bajarilishi kerak;
  • bir xil amalni bir nechta serverga qo'llash kerak.

Skript dasturlash tili emas — u mavjud buyruqlarni tartibga soladigan shell. Og'ir hisob-kitoblar yoki katta hajmdagi ma’lumotlarni qayta ishlash uchun odatda Python kabi to'liq dasturlash tili tanlanadi. Lekin tizim administratorining kundalik ishining katta qismi — fayllar, jarayonlar va buyruqlarni boshqarish — aynan Bash skript darajasida hal qilinadi.

Birinchi skriptingiz

Oddiy matn muharriri (nano, vim) yordamida hello.sh nomli fayl yarating:

#!/bin/bash

# This script prints a simple greeting
echo "Hello, Linux!"

Faylni bajariladigan qilish va ishga tushirish:

chmod +x hello.sh
./hello.sh
Hello, Linux!

chmod +x faylga execute ruxsatini qo'shadi. Bu ruxsat bo'lmasa, matn to'g'ri yozilgan bo'lsa ham, tizim faylni skript sifatida ishga tushirishga yo'l qo'ymaydi. Ruxsatlarning to'liq mantiqi Fayl ruxsatlari maqolasida ko'rib chiqilgan. Skript uchun muhimi shuki, egasida (yoki tegishli group/others toifasida) x biti bo'lishi kerak.

Shebang: interpreterni tanlash

Skriptning birinchi qatori — #!/bin/bash — shebang deb ataladi (# — "sharp", ! — "bang", birgalikda qisqartirilib "shebang"). Bu qator tizimga fayldagi buyruqlarni qaysi dastur bajarishi kerakligini aytadi. Skript ./hello.sh ko'rinishida ishga tushirilganda, tizim aslida shebang'da ko'rsatilgan dasturni ishga tushiradi va skript yo'lini unga argument sifatida uzatadi. Ya’ni haqiqatda bajariladigan buyruq /bin/bash ./hello.sh ko'rinishida bo'ladi. Buni jarayonlar jadvalida tekshirish mumkin:

sleep 100 &
ps -ef | grep sleep

Agar sleep o'rniga shebang'li skript ishga tushirilsa, ps -ef chiqishida aynan /bin/bash /path/script.sh ko'rinishidagi qator chiqadi. Bu shebang nima qilishini isbotlaydi.

Ikki xil shakl mavjud:

#!/bin/bash
#!/usr/bin/env bash

Birinchisi bashning aniq yo'lini ko'rsatadi va ko'pchilik Linux distributivlarida to'g'ri ishlaydi. Ikkinchisi bashni env dasturi yordamida PATH orqali topadi. U ko'proq ko'chiriluvchanlik (portability) kerak bo'lganda ishlatiladi, masalan, turli tizimlarda bash boshqa yo'lga o'rnatilgan bo'lishi mumkin bo'lsa. Bu kursda va production Linux serverlarida bash deyarli har doim /bin/bash da joylashgan, shuning uchun #!/bin/bash shakli ishlatiladi.

Shebang faqat bash uchun emas — u istalgan interpreterni ko'rsatishi mumkin:

#!/bin/sh
#!/usr/bin/python3
#!/usr/bin/perl

Agar shebang umuman yozilmasa, skript joriy interaktiv shell orqali ishga tushadi. Bu ba’zan ishlayotgandek ko'rinadi, lekin ishonchli emas: turli foydalanuvchilarning standart shell’i har xil bo'lishi mumkin (bash, zsh, dash), ularning sintaksisi esa bir xil emas. Shuning uchun shebang'ni aniq yozish har doim to'g'ri amaliyot.

Note

Ba’zi distributivlarda (masalan, Debian/Ubuntu) /bin/sh aslida bashga emas, dashga ishora qiladi. dash — POSIX shell bo'lib, Bash’ning ko'plab qulay kengaytmalarini (massivlar, [[ ]], local va boshqalar) qo'llab-quvvatlamaydi. Shuning uchun Bash’ga xos sintaksisdan foydalanadigan skriptning shebang'i #!/bin/sh emas, aynan #!/bin/bash bo'lishi kerak.

Skriptni ishga tushirishning ikki usuli

1. Nisbiy yoki absolyut yo'l bilan:

./hello.sh
/home/<username>/scripts/hello.sh

Bu usul skript joylashgan katalog PATH o'zgaruvchisida bo'lmasa ham ishlaydi, chunki yo'l aniq ko'rsatilgan. ./ belgisi joriy katalogni bildiradi. Uni tushirib qoldirib bo'lmaydi, aks holda shell skriptni PATH ichidan qidiradi va odatda topa olmaydi.

2. Faqat nomi bilan (agar skript PATH ichida bo'lsa):

hello.sh

Bu faqat skript joylashgan katalog $PATH o'zgaruvchisiga qo'shilgan bo'lsagina ishlaydi. Alias’lar va muhit o'zgaruvchilari maqolasida ko'rilgan PATH mexanizmi bu yerda ham aynan shunday ishlaydi: shell buyruq nomini PATH da sanab o'tilgan kataloglardan qidiradi.

Skriptni interpreterni to'g'ridan-to'g'ri chaqirib ham ishga tushirish mumkin. Bu holda execute ruxsati (x biti) talab qilinmaydi, chunki faylni bashning o'zi o'qiydi:

bash hello.sh

Bu tezkor tekshiruv uchun qulay. Lekin muntazam ishlatiladigan skript uchun chmod +x berib, uni mustaqil bajariladigan fayl sifatida saqlash tavsiya etiladi.

Izohlar (comments)

# belgisidan keyingi hamma narsani interpreter e’tiborsiz qoldiradi — bu izoh (comment). Shebang bundan mustasno, chunki u maxsus birinchi qator sifatida talqin qilinadi:

#!/bin/bash

# This whole line is a comment
echo "Hello"  # The right-hand side of this line is also a comment

Izohlar kod uchun emas, kodni o'qiydigan odam uchun yoziladi. Yaxshi skriptdagi izoh biror narsa nima qilishini emas (buni buyruqning o'zi ko'rsatib turibdi), balki nega aynan shunday yozilganini tushuntiradi. Masalan, nostandart yechimning sababi yoki ko'zga tashlanmaydigan cheklov.

Skriptni tekshirish: shellcheck

Skript uzaygan sari kichik xatolar (noto'g'ri yozilgan o'zgaruvchi nomi, unutilgan qo'shtirnoq) e’tibordan chetda qolishi mumkin. shellcheck — Bash skriptlari uchun statik tahlil vositasi bo'lib, keng tarqalgan xatolarni yozish bosqichidayoq ushlaydi:

sudo apt install shellcheck
shellcheck hello.sh
In hello.sh line 4:
echo "Hello, Linux!"
^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang.

(Bu misolda shellcheck shu haqda ogohlantirishini ko'rsatish uchun shebang ataylab olib tashlangan.) Bu modul davomida yoziladigan har bir skriptni shellcheck dan o'tkazish tavsiya etiladi. Bu, ayniqsa, keyingi maqolalarda o'zgaruvchilar va shartlar paydo bo'lganda foydali.

Skriptni debug qilish: bash -x va set -x

shellcheck xatolarni skript ishga tushishidan oldin ushlaydi. -x (xtrace) esa skript ishlayotgan, lekin noto'g'ri ish qilayotgan va sababini ko'ra olmayotgan holatda yordam beradi. U har bir buyruqni barcha o'zgaruvchi va buyruq almashtirishlaridan (substitution) keyin, bajarilishidan bevosita oldin chiqaradi. Shunday qilib, siz o'zingiz taxmin qilgan qiymatlarni emas, Bash haqiqatda ishlatgan qiymatlarni ko'rasiz.

Butun skriptni o'zgartirmasdan trace rejimida ishga tushirish:

bash -x hello.sh
+ echo 'Hello, Linux!'
Hello, Linux!

Trace qilingan har bir qator oldida + belgisi turadi. Butun skriptni emas, faqat shubhali qismini trace qilish uchun uni set -x/set +x orasiga oling:

#!/bin/bash
name="Linux"
set -x            # tracing on
greeting="Hello, ${name}!"
set +x            # tracing off
echo "$greeting"
+ greeting='Hello, Linux!'
+ set +x
Hello, Linux!

Bu intervyudagi klassik savolga — "skript kutilganidek ishlamayapti, uni qanday debug qilasiz?" — eng tez javob: statik xatolar uchun shellcheck, so'ng haqiqiy, kengaytirilgan (expanded) buyruqlarni bajarilish paytida kuzatish uchun bash -x (yoki ma’lum qism uchun set -x).

Tip

Buni Exit kodlar va xatolarni qayta ishlash maqolasidagi qat’iy flag'lar bilan birlashtiring: skriptni bash -xeuo pipefail script.sh ko'rinishida ishga tushirish har bir buyruqni trace qiladi va birinchi xatoda hamda birinchi e’lon qilinmagan o'zgaruvchida to'xtaydi. Bu debug qilish uchun eng foydali bir qatorli chaqiruv.

Keng tarqalgan xatolar

Execute ruxsati berilmagan

bash: ./hello.sh: Permission denied

Sababi — faylda x biti yo'q. Yechim: chmod +x hello.sh.

./ ni unutish

bash: hello.sh: command not found

Joriy katalog odatda PATH ichida bo'lmaydi, shuning uchun shell skriptni topa olmaydi. Yechim: ./hello.sh deb yozing yoki absolyut yo'lni ko'rsating.

Shebang qatorida bo'sh joy yoki noto'g'ri belgi

# !/bin/bash

# va ! orasida bo'sh joy qoldirilsa, qator oddiy izohga aylanadi va shebang ishlamay qoladi. Skript joriy shell orqali ishga tushadi, bu esa kutilmagan xatti-harakatga olib kelishi mumkin.

Windows’da tahrirlangan fayldagi qator oxiri belgilari (CRLF)

Agar skript Windows’da tahrirlanib, keyin Linux serverga ko'chirilsa, quyidagi xato chiqishi mumkin:

bash: ./hello.sh: /bin/bash^M: bad interpreter: No such file or directory

Sababi — Windows qator oxirini \r\n (CRLF) bilan belgilaydi, Linux esa faqat \n dan foydalanadi. Ortiqcha \r belgisi shebang qatoriga qo'shilib qoladi va yo'lni buzadi. Tekshirish va tuzatish:

file hello.sh
sed -i 's/\r$//' hello.sh

Mashqlar

  1. whoami, hostname va date chiqishini ketma-ket chiqaradigan whoami.sh nomli skript yozing. Uni bajariladigan qiling va ikkala usulda (./whoami.sh va bash whoami.sh) ishga tushiring.
  2. Shebang qatorini ataylab # !/bin/bash ko'rinishida (o'rtada bo'sh joy bilan) yozing va nima o'zgarishini kuzating.
  3. 1-mashqdagi skriptni shellcheck bilan tekshiring va chiqishini tahlil qiling.

Xulosa

Bash skript buyruqlar ketma-ketligini bitta bajariladigan faylga birlashtiradi. Shebang qatori qaysi interpreter ishlatilishini belgilaydi, chmod +x esa faylga execute ruxsatini beradi — bu ikkisi har qanday skriptning poydevori. Keyingi maqola, O'zgaruvchilar va argumentlar, skript ichida ma’lumotlarni qanday saqlash va ularni tashqaridan (buyruq qatori orqali) qanday uzatishni ko'rib chiqadi. Bu skriptni buyruqlarning statik ro'yxatidan moslashuvchan vositaga aylantiradi.

Manbalar