Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. Birinchi skript
- 2.1 Faylni yaratish
- 2.2 Ishga tushirish: bash salom.sh
- 2.3 Shebang va ./salom.sh
- 3. O'zgaruvchilar va argumentlar
- 3.1 Skript ichida o'zgaruvchi
- 3.2 Tashqaridan qiymat: $1, $2
- 3.3 Bo'sh joyli argument
- 3.4 Ishlayotgan paytda so'rash: read
- 4. Qo'shtirnoq qoidalari
- 5. Shart: if
- 5.1 Tuzilishi
- 5.2 [ ] aslida nima?
- 5.3 Eng ko'p kerak bo'ladigan tekshiruvlar
- 5.4 exit — skriptni to'xtatish va kod qaytarish
- 6. Sikl: for
- 7. Xavfsiz skript: set -euo pipefail
- 7.1 Muammo: bash xatodan keyin ham davom etadi
- 7.2 Yechim
- 8. Mini-loyiha: zaxira.sh
- 9. Ko'p uchraydigan xatolar
- 9.1 = atrofida bo'sh joy
- 9.2 [ yonida bo'sh joy yo'q
- 9.3 Qo'shtirnoqsiz bo'sh o'zgaruvchi
- 9.4 Songa matn berish
- 9.5 Windows'da yozilgan skript Linux'da ishlamaydi
- 9.6 Permission denied
- 10. Mashqlar
- 1-mashq (oson): Bo'sh joylarni to'ldiring
- 2-mashq (o'rta): Oylik papkalar
- 3-mashq (qiyin): Fayl hisobchisi
- 11. Real ishda
- Xulosa
Shell skript yozish asoslari: bash'da birinchi avtomatlashtirish
Qisqacha: Shell skript — terminal buyruqlari ketma-ket yozilgan matnli fayl (odatda
.sh). Birinchi qatori — shebang#!/usr/bin/env bash: "meni bash bajarsin". Ishga tushirish:bash skript.shyokichmod +x skript.shdan keyin./skript.sh. Ichida o'zgaruvchilar,$1(birinchi argument),if,forishlatiladi.set -eskriptni birinchi xatoda to'xtatadi.
Bu darsda
- Birinchi skriptingizni yozib, uni ikki usulda ishga tushirasiz.
- Shebang qatori va
chmod +xnima uchun kerakligini tushuntira olasiz. - Skriptga tashqaridan qiymat berasiz:
$1,$2,$#,$@. - Qo'shtirnoq qoidalarini bilasiz:
"..."ichida o'zgaruvchi ochiladi,'...'ichida — yo'q. ifbilan tekshirasiz,forbilan takrorlaysiz,set -euo pipefailbilan skriptni xavfsiz qilasiz.
Oldin bilishingiz kerak: Exit code va buyruqlarni zanjirlash, Muhit o'zgaruvchilari va PATH, Fayl ruxsatlari va foydalanuvchilar.
1. Nega bu kerak?
Tasavvur qiling: har kuni ish oxirida sayt papkangizning zaxira nusxasini olasiz. Buning uchun uch buyruq yozasiz: zaxira papkasini yaratish, bugungi sanani aniqlash, nusxalash. Har kuni, qo'lda.
Bir kuni sanani adashtirasiz. Boshqa kuni cp dagi -r ni unutasiz. Bir haftadan keyin esa umuman unutib qo'yasiz.
Yechim — bu buyruqlarni bir marta faylga yozib qo'yish. Keyin bitta buyruq bilan hammasi bajariladi:
./zaxira.sh saytTayyor: zaxira/sayt-2026-09-27Bunday fayl shell skript (shell script) deyiladi. Bu dars oxirida aynan shu zaxira.sh ni o'zingiz yozasiz.
O'xshatish: plov retsepti. Har safar oshpazdan "endi nima qilay?" deb so'ramaysiz — retsept daftarga yozilgan, qadamlari tartib bilan. Skript — kompyuter uchun yozilgan retsept.
2. Birinchi skript
2.1 Faylni yaratish
Git Bash, WSL yoki macOS terminalida mashq papkasini oching:
mkdir -p skriptlar
cd skriptlarEndi salom.sh faylini yarating. Uni VS Code'da (code salom.sh) yoki muhit o'zgaruvchilari darsidagi nano da (nano salom.sh) ochib, quyidagini yozing:
#!/usr/bin/env bash
# Birinchi skriptim
echo "Assalomu alaykum!"
echo "Bugun: $(date +%d.%m.%Y)"
echo "Siz turgan papka: $(pwd)"Qatorma-qator:
#!/usr/bin/env bash— shebang. Uni sal pastda batafsil ko'ramiz.# Birinchi skriptim— izoh.#dan keyingi hamma narsani bash o'qimaydi. Izoh odamlar uchun: "bu skript nima qiladi".echo "Assalomu alaykum!"— tanishecho.$(date +%d.%m.%Y)— yangi narsa: buyruq natijasini o'rniga qo'yish. Bash avval qavs ichidagidateni bajaradi va uning natijasini (27.09.2026) satrga qo'yadi.+%d.%m.%Y—datega "kun.oy.yil ko'rinishida chiqar" degan buyruq.$(pwd)— xuddi shunday: joriy papka yo'li.
2.2 Ishga tushirish: bash salom.sh
Eng oddiy usul — bash dasturiga faylni berish:
bash salom.shAssalomu alaykum!
Bugun: 27.09.2026
Siz turgan papka: /home/ali/skriptlarBash faylni ochdi va ichidagi buyruqlarni yuqoridan pastga, birma-bir bajardi — xuddi siz ularni terminalga qo'lda yozgandek.
2.3 Shebang va ./salom.sh
Har safar bash deb yozmasdan, skriptni oddiy dastur kabi ishga tushirish mumkin. Buning uchun ikki narsa kerak.
Birinchisi — shebang. Fayl boshidagi #! belgilari (inglizcha "sharp" + "bang" — # va ! belgilari nomlaridan) operatsion tizimga aytadi: "bu faylni qaysi dastur bajarsin". /usr/bin/env bash esa "PATH'dan bash ni topib, o'shanga ber" degani. Nega to'g'ridan-to'g'ri /bin/bash emas? Chunki turli tizimlarda bash turli joyda bo'ladi, env esa uni PATH bo'yicha o'zi topadi.
Ikkinchisi — bajarish huquqi. Fayl ruxsatlari darsida x (execute) huquqini ko'rgan edik. Yangi fayl odatda bu huquqsiz yaratiladi:
chmod +x salom.sh
./salom.shNatija bash salom.sh dagidek.
Nega ./? PATH darsidan eslang: nomi bilan yozilgan buyruq faqat PATH papkalaridan qidiriladi. Joriy papka PATH'da yo'q — bu xavfsizlik uchun ataylab qilingan. ./ — "aynan shu papkadagi fayl" degan aniq yo'l.
salom.shbash: salom.sh: command not found./salom.sh yozganingizda nima bo'lishini bir rasmda ko'ramiz:
flowchart TD
A["./salom.sh"] --> B{"Faylda x huquqi bormi?"}
B -- "yo'q" --> X["Permission denied, kod 126"]
B -- "ha" --> C["OS birinchi qatorni o'qiydi:<br/>#!/usr/bin/env bash"]
C --> D["env PATH'dan bash'ni topadi"]
D --> E["bash faylni qatorma-qator bajaradi"]Maslahat: Git Bash'da (Windows'da)
chmod +xta'sir qilmaydi: Windows'daxhuquqi yo'q, shuning uchun Git Bash#!bilan boshlangan faylni o'zi bajariladigan deb hisoblaydi. Linux, macOS va WSL'da esachmod +xmajburiy. Serverlar Linux'da — odatni hozirdan shakllantiring.
Tekshirib ko'ring: Linux'da yangi
hisobot.shyaratdingiz va darhol./hisobot.shyozdingiz. Nima bo'ladi va qanday tuzatasiz? Yana qaysi usulchmodsiz ham ishlaydi?
Javob
bash: ./hisobot.sh: Permission denied xatosi (exit code 126). Faylda x huquqi yo'q. Tuzatish: chmod +x hisobot.sh. chmod siz ishlaydigan usul — bash hisobot.sh: bu holda fayl dastur sifatida emas, bash uchun matn sifatida o'qiladi va x huquqi kerak emas.
3. O'zgaruvchilar va argumentlar
3.1 Skript ichida o'zgaruvchi
O'zgaruvchilar muhit o'zgaruvchilari darsidagi qoidalar bilan ishlaydi: nom=qiymat (bo'sh joysiz), o'qish — $nom. Hisob-kitob uchun esa $(( ... )) ishlatiladi:
#!/usr/bin/env bash
narx=12000
soni=3
jami=$((narx * soni))
echo "Jami: $jami so'm"Jami: 36000 so'm$(( )) ichida +, -, *, / ishlaydi va o'zgaruvchilarni $ siz yozsa ham bo'ladi. Faqat butun sonlar: $((7 / 2)) — 3, kasr qismi tashlanadi.
3.2 Tashqaridan qiymat: $1, $2
Skript har safar bir xil ish qilsa, uning foydasi kam. Unga tashqaridan qiymat berish uchun argumentlar ishlatiladi — buyruq anatomiyasi darsidagi argumentlarning o'zi. Skript ichida ular maxsus o'zgaruvchilarda turadi:
| O'zgaruvchi | Nima |
|---|---|
$1, $2, ... |
1-, 2-, ... argument |
$# |
Argumentlar soni |
$@ |
Barcha argumentlar |
$0 |
Skriptning o'z nomi |
mehmon.sh:
#!/usr/bin/env bash
echo "Xush kelibsiz, $1!"
echo "Siz ${2}dan keldingiz."
echo "Argumentlar soni: $#"bash mehmon.sh Malika SamarqandXush kelibsiz, Malika!
Siz Samarqanddan keldingiz.
Argumentlar soni: 2${2}dan — muhit o'zgaruvchilari darsidagi jingalak qavs: shundan keyin qo'shimcha yopishib keladi. $2dan desak ham bu yerda ishlardi (raqamli nom bitta raqamdan iborat), lekin ${...} odati adashishdan saqlaydi.
3.3 Bo'sh joyli argument
Argumentlar bo'sh joy bilan ajratiladi. Ism va familiyani bitta argument qilish uchun — qo'shtirnoq:
bash mehmon.sh Ali Valiyev Toshkent
bash mehmon.sh "Ali Valiyev" ToshkentXush kelibsiz, Ali!
Siz Valiyevdan keldingiz.
Argumentlar soni: 3
Xush kelibsiz, Ali Valiyev!
Siz Toshkentdan keldingiz.
Argumentlar soni: 2Birinchi holatda Valiyev ikkinchi argument bo'lib qoldi — "Valiyevdan keldingiz". Qo'shtirnoq uch so'zni ikkita argumentga aylantirdi.
Tekshirib ko'ring:
bash mehmon.sh(argumentsiz) nima chiqaradi?
Javob
Xush kelibsiz, !, Siz dan keldingiz. va Argumentlar soni: 0. Berilmagan argument — bo'sh qator. Bash xato bermaydi, jimgina bo'sh qo'yadi. Bu xavfli bo'lishi mumkin — shuning uchun quyida argument bor-yo'qligini tekshirishni va set -u sozlamasini o'rganamiz.
3.4 Ishlayotgan paytda so'rash: read
Argument — skript boshlanishidan oldin beriladi. Ba'zan esa qiymatni ish davomida so'rash qulayroq. Buni read qiladi: u foydalanuvchi yozib, Enter bosishini kutadi va yozilganini o'zgaruvchiga soladi. sora.sh:
#!/usr/bin/env bash
read -p "Ismingiz: " ism
echo "Salom, $ism!"-p (prompt) — kutishdan oldin ko'rsatiladigan savol matni. bash sora.sh ni ishga tushirib, Jasur deb yozing:
Ismingiz: Jasur
Salom, Jasur!Qaysi biri yaxshiroq? Argument — avtomatik ishlaydigan skriptlar uchun (CI, jadval bo'yicha ishga tushadigan skriptlar): u yerda klaviatura oldida hech kim o'tirmaydi. read — odam bilan "gaplashadigan" kichik yordamchi skriptlar uchun.
4. Qo'shtirnoq qoidalari
Bash'da qo'shtirnoq turi natijani o'zgartiradi. Uchta qoida yetarli.
1. Ikkitalik "..." — o'zgaruvchi ochiladi:
ism="Ali"
echo "Salom, $ism"Salom, Ali2. Bittalik '...' — hamma narsa aynan qanday bo'lsa, shunday:
echo 'Salom, $ism'Salom, $ismBittalik qo'shtirnoq ichida $ oddiy belgi. Ikkitalik ichida bitta $ ni oddiy belgi qilish uchun oldiga \ qo'yiladi: "Narx: \$5" — Narx: $5.
3. O'zgaruvchini doim ikkitalik qo'shtirnoqqa oling:
fayl="oylik hisobot.txt"
touch "$fayl"
ls $faylls: cannot access 'oylik': No such file or directory
ls: cannot access 'hisobot.txt': No such file or directoryQo'shtirnoqsiz $fayl ochilganda bo'sh joy bo'yicha ikki bo'lakka bo'lindi va ls ikkita yo'q faylni qidirdi. ls "$fayl" esa to'g'ri ishlaydi. Qoida oddiy: $ism emas — "$ism". Fayl nomlarida bo'sh joy tez-tez uchraydi, va bu qoida sizni ko'p xatodan saqlaydi.
| Yozuv | ism="Ali" bo'lsa natija |
|---|---|
"Salom, $ism" |
Salom, Ali |
'Salom, $ism' |
Salom, $ism |
"Narx: \$5" |
Narx: $5 |
Tekshirib ko'ring:
shahar="Toshkent"dan keyinecho "Men $shahar'da"vaecho 'Men $shahar da'nima chiqaradi?
Javob
Birinchisi — Men Toshkent'da: ikkitalik qo'shtirnoq ichidagi apostrof oddiy belgi, o'zgaruvchi esa ochildi (apostrof nomga kirmaydi, shuning uchun ${} shart emas edi). Ikkinchisi — Men $shahar da: bittalik qo'shtirnoq ichida hech narsa ochilmaydi.
5. Shart: if
5.1 Tuzilishi
if — "agar ... bo'lsa, ... qil, aks holda ...". tekshir.sh:
#!/usr/bin/env bash
if [ -f "$1" ]; then
echo "$1 — fayl, bor."
elif [ -d "$1" ]; then
echo "$1 — papka."
else
echo "$1 topilmadi."
fiBo'laklaymiz:
if [ shart ]; then— "agar shart to'g'ri bo'lsa, unda".elif— "aks holda, agar" (else if). Ixtiyoriy, bir nechta bo'lishi mumkin.else— "aks holda". Ixtiyoriy.fi—ifning oxiri (ifni teskari o'qing).- Ichkaridagi qatorlar ikki bo'sh joy bilan suriladi — faqat o'qish qulayligi uchun.
touch menyu.txt
mkdir -p rasmlar
bash tekshir.sh menyu.txt
bash tekshir.sh rasmlar
bash tekshir.sh yoq.txtmenyu.txt — fayl, bor.
rasmlar — papka.
yoq.txt topilmadi.5.2 [ ] aslida nima?
[ — aslida buyruq (test buyrug'ining boshqa nomi). U shartni tekshiradi va exit code qaytaradi: 0 — to'g'ri, 1 — noto'g'ri. if esa shunchaki exit code'ga qaraydi. Shuning uchun [ dan keyin va ] dan oldin bo'sh joy majburiy — bu buyruq va uning argumentlari.
Va shuning uchun if dan keyin istalgan buyruqni yozish mumkin: if grep -q "TODO" app.js; then ... — grep topsa (0), shart to'g'ri.
5.3 Eng ko'p kerak bo'ladigan tekshiruvlar
Fayllar va matn uchun:
| Shart | To'g'ri, agar |
|---|---|
[ -f "$f" ] |
$f — mavjud fayl |
[ -d "$d" ] |
$d — mavjud papka |
[ -z "$s" ] |
$s bo'sh (zero length) |
[ "$a" = "$b" ] |
Ikki matn teng |
Sonlar uchun — so'zlar bilan (PowerShell'dagidek):
| Shart | Ma'nosi |
|---|---|
-eq |
teng (equal) |
-ne |
teng emas (not equal) |
-gt / -ge |
katta / katta yoki teng |
-lt / -le |
kichik / kichik yoki teng |
Nega sonlar uchun > emas? Chunki > faylga yo'naltirish uchun band. [ $a > 5 ] yozsangiz, bash 5 degan fayl yaratadi!
#!/usr/bin/env bash
son=$1
if [ "$son" -gt 100 ]; then
echo "Katta buyurtma"
else
echo "Oddiy buyurtma"
fibash son.sh 150 — Katta buyurtma, bash son.sh 5 — Oddiy buyurtma.
5.4 exit — skriptni to'xtatish va kod qaytarish
Skript ham dastur, u ham exit code qaytaradi. Odatda — oxirgi bajarilgan buyruqning kodi. O'zingiz belgilash uchun — exit N. Argument berilmasa, yo'riqnoma chiqarib, xato bilan chiqamiz:
if [ $# -eq 0 ]; then
echo "Ishlatish: ./tekshir.sh <fayl>" >&2
exit 1
fi>&2 — echo natijasini stderr'ga yuborish (1>&2 ning qisqasi, oqimlar darsidagi 2>&1 ning teskarisi). Xato xabarlari stderr'ga yoziladi — shunda ular natija bilan aralashmaydi. exit 1 esa chaqirgan odamga (yoki CI'ga) "muvaffaqiyatsiz" deydi.
Tekshirib ko'ring:
[ "$ism" = "Ali" ]va["$ism" = "Ali"]— qaysi biri ishlaydi?
Javob
Birinchisi. Ikkinchisida [ dan keyin bo'sh joy yo'q — bash ["Ali" ni (ya'ni [Ali) bitta buyruq nomi deb o'qiydi va [Ali: command not found xatosini beradi.
6. Sikl: for
for — ro'yxatdagi har bir element uchun bir xil ishni takrorlaydi:
#!/usr/bin/env bash
for taom in osh somsa manti; do
echo "Menyuda: $taom"
doneMenyuda: osh
Menyuda: somsa
Menyuda: mantifor taom in ...— "ro'yxatdagi har bir element uchun, unitaomdeb atab".do...done— har safar bajariladigan qism.
Ro'yxat o'rnida glob juda qulay — papkadagi fayllar ustida ishlash:
for fayl in *.txt; do
echo "Topildi: $fayl"
doneYoki skriptga berilgan barcha argumentlar ustida: for fayl in "$@"; do. "$@" qo'shtirnoqda — shunda bo'sh joyli argumentlar bo'linib ketmaydi.
Sonlar ketma-ketligi uchun: for i in {1..5}; do — 1 dan 5 gacha.
Tekshirib ko'ring: Quyidagi sikl nechta papka yaratadi va qanday nomlar bilan?
bashfor oy in yanvar fevral mart; do mkdir -p "hisobot/$oy" done
Javob
Uchta: hisobot/yanvar, hisobot/fevral, hisobot/mart (va ularning ota papkasi hisobot, -p tufayli). Sikl har bir oy uchun mkdir ni bir marta bajaradi.
7. Xavfsiz skript: set -euo pipefail
7.1 Muammo: bash xatodan keyin ham davom etadi
xavfli.sh:
#!/usr/bin/env bash
cd /yoq-papka
echo "Hozir shu papkadaman: $(pwd)"xavfli.sh: line 2: cd: /yoq-papka: No such file or directory
Hozir shu papkadaman: /home/ali/skriptlarcd yiqildi, lekin skript davom etdi — va noto'g'ri papkada ishlashni boshladi. Endi tasavvur qiling, ikkinchi qator echo emas, rm -rf * bo'lsa. Bash kerakli papkani emas, siz turgan papkani tozalab tashlardi — skriptni uy papkangizdan ishga tushirgan bo'lsangiz, uy papkangizni. Bu — exit code darsidagi ; muammosining o'zi: skriptdagi qatorlar odatda ; bilan ajratilgandek bajariladi.
7.2 Yechim
Skript boshiga, shebang'dan keyin bitta qator:
#!/usr/bin/env bash
set -euo pipefail
cd /yoq-papka
echo "Bu qator chiqmaydi"xavfsiz.sh: line 3: cd: /yoq-papka: No such file or directorySkript cd da to'xtadi va exit code 1 qaytardi. Uchta sozlama:
| Sozlama | Nima qiladi |
|---|---|
-e |
Birorta buyruq xato bersa (0 emas) — skript to'xtaydi |
-u |
Yaratilmagan o'zgaruvchi ishlatilsa — xato |
-o pipefail |
Pipe'dagi birorta bo'lak yiqilsa — butun zanjir xato |
-u ning foydasi: $ism da harf xatosi qilsangiz ($ims), bash jimgina bo'sh qo'ymaydi, balki ims: unbound variable ("bog'lanmagan o'zgaruvchi") deb to'xtaydi. pipefail ni exit code darsida ko'rgan edik.
Qoida: har bir yangi skript shu ikki qator bilan boshlansin:
#!/usr/bin/env bash
set -euo pipefailDiqqat:
set -ubilan$1ga to'g'ridan-to'g'ri murojaat argument berilmasa xato beradi ($1: unbound variable). Shuning uchun argumentlarni avval$#bilan tekshiring —$#doim mavjud.
8. Mini-loyiha: zaxira.sh
Endi 1-bo'limdagi vazifaga qaytamiz. Hamma bo'lakni birlashtiramiz:
#!/usr/bin/env bash
set -euo pipefail
if [ $# -eq 0 ]; then
echo "Ishlatish: ./zaxira.sh <papka>" >&2
exit 1
fi
manba="$1"
sana=$(date +%Y-%m-%d)
nusxa="zaxira/${manba}-${sana}"
mkdir -p zaxira
cp -r "$manba" "$nusxa"
echo "Tayyor: $nusxa"Qator-qator:
- Shebang va xavfsizlik sozlamasi.
- Argument yo'q bo'lsa — yo'riqnoma stderr'ga,
exit 1. manba— nusxalanadigan papka,sana— bugungi sana (2026-09-27ko'rinishida — bunday tartib fayllarni sana bo'yicha to'g'ri saralaydi).nusxa— nusxa yo'li,${}bilan chegaralangan.mkdir -p— zaxira papkasini yaratadi (bor bo'lsa, jim).cp -r— papkani ichidagilari bilan nusxalaydi. O'zgaruvchilar qo'shtirnoqda.
Sinab ko'ramiz:
chmod +x zaxira.sh
mkdir -p sayt
touch sayt/index.html
./zaxira.sh
./zaxira.sh sayt
./zaxira.sh yoqpapkaIshlatish: ./zaxira.sh <papka>
Tayyor: zaxira/sayt-2026-09-27
cp: cannot stat 'yoqpapka': No such file or directoryUchinchi holatda cp yiqildi va set -e skriptni to'xtatdi — Tayyor degan yolg'on xabar chiqmadi.
9. Ko'p uchraydigan xatolar
9.1 = atrofida bo'sh joy
skript.sh: line 2: ism: command not foundism = "Ali" yozilgan. Muhit o'zgaruvchilari darsidagidek: bash ism ni buyruq deb o'qidi. Tuzatish: ism="Ali".
9.2 [ yonida bo'sh joy yo'q
skript.sh: line 1: [prod: command not foundif ["$1" = "prod"] yozilgan. [ — buyruq, u so'zdan bo'sh joy bilan ajralishi shart. Tuzatish: if [ "$1" = "prod" ].
9.3 Qo'shtirnoqsiz bo'sh o'zgaruvchi
skript.sh: line 3: [: =: unary operator expectedif [ $rejim = "prod" ] yozilgan, rejim esa bo'sh. Qo'shtirnoqsiz bo'sh o'zgaruvchi "yo'qolib", bash [ = "prod" ] ni ko'rdi va chalkashdi. Tuzatish: [ "$rejim" = "prod" ] — endi u [ "" = "prod" ] bo'ladi va shunchaki "noto'g'ri" deydi.
9.4 Songa matn berish
bash son.sh abcson.sh: line 3: [: abc: integer expression expected"Butun son kutilgan edi" (bash 5.3 da xabar qisqaroq: integer expected). -gt faqat sonlar bilan ishlaydi. Foydalanuvchi nima berishini oldindan bilmaysiz — muhim skriptlarda argumentni tekshiring.
9.5 Windows'da yozilgan skript Linux'da ishlamaydi
Skriptni Windows'da yozib, serverga ko'chirdingiz va:
/usr/bin/env: 'bash\r': No such file or directory"bash\r topilmadi". \r — qator oxiri darsidagi CR belgisi: fayl Windows qator oxiri (CRLF) bilan saqlangan. Linux shebang'ni bash\r deb o'qidi. Git Bash buni kechiradi, Linux — yo'q. Tuzatish: VS Code'ning pastki o'ng burchagida CRLF ni LF ga almashtiring yoki dos2unix skript.sh.
9.6 Permission denied
bash: ./zaxira.sh: Permission deniedLinux, macOS yoki WSL'da chmod +x qilinmagan (exit code 126). Tuzatish: chmod +x zaxira.sh yoki bash zaxira.sh.
10. Mashqlar
1-mashq (oson): Bo'sh joylarni to'ldiring
salom.sh skripti birinchi argumentdagi ism bilan salomlashsin va argumentlar sonini aytsin. Bo'sh joylarni to'ldiring:
- Birinchi argument saqlanadigan o'zgaruvchi:
$ - Argumentlar soni saqlanadigan o'zgaruvchi:
$ - Linux'da faylga bajarish huquqini berish:
chmodsalom.sh
Keyin skriptni to'liq yozing: shebang, xavfsizlik qatori va ikkita echo.
Yechim
#!/usr/bin/env bash
set -euo pipefail
echo "Salom, $1!"
echo "Argumentlar soni: $#"bash salom.sh Jasur natijasi:
Salom, Jasur!
Argumentlar soni: 1$1 — birinchi argument, $# — argumentlar soni. chmod +x — bajarish huquqi. Diqqat: set -u tufayli argumentsiz ishga tushirsangiz, $1: unbound variable xatosi chiqadi — bu kutilgan xatti-harakat.
2-mashq (o'rta): Oylik papkalar
oylar.sh skriptini yozing. U for sikli bilan hisobot/yanvar, hisobot/fevral, hisobot/mart papkalarini yaratsin va har biri uchun Yaratildi: hisobot/yanvar kabi xabar chiqarsin. Skript xavfsizlik qatori bilan boshlansin.
Yechim
#!/usr/bin/env bash
set -euo pipefail
for oy in yanvar fevral mart; do
mkdir -p "hisobot/$oy"
echo "Yaratildi: hisobot/$oy"
doneYaratildi: hisobot/yanvar
Yaratildi: hisobot/fevral
Yaratildi: hisobot/mart-p ikki ishni qiladi: hisobot yo'q bo'lsa — yaratadi, papka allaqachon bor bo'lsa — xato bermaydi. Shuning uchun skriptni ikkinchi marta ishga tushirsangiz ham set -e uni to'xtatmaydi.
3-mashq (qiyin): Fayl hisobchisi
hisob.sh skriptini yozing. Unga bir nechta fayl nomi beriladi. Har bir fayl uchun:
- fayl bor bo'lsa —
yanvar.txt: 2 qatorko'rinishida qatorlar sonini chiqarsin; - yo'q bo'lsa —
mart.txt: topilmadixabarini stderr'ga yozsin.
Argument umuman berilmasa — yo'riqnoma chiqarib, exit 1.
Ishoralar: barcha argumentlar — "$@"; qatorlar soni — oqimlar darsidagi wc -l < fayl (fayl nomisiz faqat son beradi); buyruq natijasini matnga qo'yish — $(...).
Tekshirish uchun: printf "a\nb\n" > yanvar.txt va touch fevral.txt, keyin bash hisob.sh yanvar.txt fevral.txt mart.txt.
Yechim
#!/usr/bin/env bash
set -euo pipefail
if [ $# -eq 0 ]; then
echo "Ishlatish: ./hisob.sh <fayl>..." >&2
exit 1
fi
for fayl in "$@"; do
if [ -f "$fayl" ]; then
echo "$fayl: $(wc -l < "$fayl") qator"
else
echo "$fayl: topilmadi" >&2
fi
doneyanvar.txt: 2 qator
fevral.txt: 0 qator
mart.txt: topilmadi$# -eq 0— argumentlar soni nolga tengmi.for fayl in "$@"— har bir argument ustida; qo'shtirnoq bo'sh joyli nomlarni saqlaydi.$(wc -l < "$fayl")—<bilanwcfaqat sonni beradi,$(...)uni satrga qo'yadi. macOS'dawcsondan oldin bo'sh joylar qo'yadi (yanvar.txt: 2 qator) — bu xato emas, shunchaki boshqacha ko'rinish.>&2— "topilmadi" xabari stderr'ga. Tekshirish:bash hisob.sh yanvar.txt mart.txt 2> /dev/null—mart.txtqatori yo'qoladi.
11. Real ishda
- Deploy skriptlari. Serverga yangi versiyani chiqarish ko'pincha
deploy.shbilan: kodni yangilash, bog'liqliklarni o'rnatish, qayta ishga tushirish. Uning birinchi ikki qatori — xuddi shu darsdagidek. - Zaxira va tozalash. Serverda har kecha avtomatik ishlaydigan skriptlar: bazaning zaxirasi, eski loglarni o'chirish. Ularni jadval bo'yicha ishga tushirishni server qismida o'rganamiz.
- CI. GitHub Actions ichidagi har bir qadam — aslida kichik bash skript. Exit code va
set -eu yerda ham hal qiluvchi. - ShellCheck. Skriptlaringizni tekshiradigan bepul vosita (
shellcheck skript.sh, VS Code kengaytmasi ham bor). U qo'shtirnoqsiz$faylkabi xatolarni ishga tushirishdan oldin topadi. - Qachon skript emas? Mantiq murakkablashsa (JSON bilan ishlash, ko'p shartlar) — Node.js yoki Python'da yozgan ma'qul. Bash — buyruqlarni bog'lash uchun, katta dasturlar uchun emas.
Xulosa
- Shell skript — buyruqlar yozilgan fayl; boshida
#!/usr/bin/env bashvaset -euo pipefail. - Ishga tushirish:
bash skript.shyokichmod +xdan keyin./skript.sh(./— chunki joriy papka PATH'da yo'q). - Argumentlar:
$1,$2,$#(soni),"$@"(hammasi); ish davomida so'rash —read -p; buyruq natijasi —$(buyruq); hisob —$((...)). "..."ichida o'zgaruvchi ochiladi,'...'ichida — yo'q; o'zgaruvchini doim"$nom"deb yozing.if [ shart ]; then ... fi—[atrofida bo'sh joy majburiy; sonlar —-eq,-gt,-lt.for x in ...; do ... done— ro'yxat, glob yoki argumentlar ustida takrorlash.
Keyingi dars: Zamonaviy CLI vositalari — klassik buyruqlarning tezroq va qulayroq zamonaviy muqobillari bilan tanishamiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!