IlmHamroh
JavaScript Full-stack/1-qism. Kompyuter, fayllar va terminal24/40-dars14 daqiqa
Mundarija (30)

Exit code va buyruqlarni zanjirlash: $?, && va ||

Qisqacha: Har bir buyruq tugaganda shell'ga bitta son qaytaradi — exit code. 0 — "muvaffaqiyatli tugadim", 1 dan 255 gacha — "xato bo'ldi". Oxirgi buyruqning kodini echo $? ko'rsatadi. && keyingi buyruqni faqat oldingisi muvaffaqiyatli bo'lsa, || — faqat xato bo'lsa, ; esa har doim ishga tushiradi.

Bu darsda

  • Exit code nima ekanini va nega muvaffaqiyat aynan 0 ekanini tushuntira olasiz.
  • echo $? bilan oxirgi buyruq qanday tugaganini tekshirasiz.
  • Eng ko'p uchraydigan kodlarni (0, 1, 2, 126, 127, 130) taniysiz.
  • ;, && va || bilan buyruqlarni zanjir qilasiz va qaysi biri qachon ishlashini aytib bera olasiz.
  • Avtomatik tekshiruv tizimlari (CI) nega exit code'ga qarab ishlashini tushunasiz.

Oldin bilishingiz kerak: Oqimlar, pipe va yo'naltirish, Fayl va matn qidirish, Buyruq anatomiyasi va yordam olish.

1. Nega bu kerak?

Tasavvur qiling: saytingizning yangi versiyasini serverga chiqaryapsiz. Buning uchun uch buyruq ketma-ket bajariladi:

  1. Yangi kodni yuklab olish.
  2. Kodni tekshirish (testlar).
  3. Saytni yangi kod bilan qayta ishga tushirish.

Agar 2-qadamda tekshiruv "kodda xato bor" desa-chi? 3-qadam baribir bajarilsa, buzilgan sayt minglab foydalanuvchiga chiqadi. Kechasi soat 3 da bu sodir bo'lsa, buni hech kim ko'rmaydi ham.

Demak, kompyuter o'zi bilishi kerak: "oldingi buyruq muvaffaqiyatli tugadimi?" Ekrandagi matnni o'qib bunga javob berish qiyin — har dastur xatoni o'zicha yozadi. Shuning uchun har bir buyruq tugaganda yana bitta, oddiy javob qaytaradi: son.

2. Exit code: dasturning "baho"si

2.1 Ta'rif

Exit code (chiqish kodi, yakunlash kodi) — dastur ishini tugatganda operatsion tizimga qaytaradigan butun son. U 0 dan 255 gacha bo'ladi.

Kod Ma'nosi
0 Muvaffaqiyat: hammasi yaxshi bo'ldi
1 – 255 Xato: nimadir noto'g'ri ketdi

O'xshatish: kuryer buyurtmani yetkazib, operatorga bitta so'z bilan xabar beradi. "Yetkazildi" — bitta variant. "Yetkazilmadi" esa o'nlab sabab bilan bo'lishi mumkin: manzil topilmadi, mijoz telefonni ko'tarmadi, yo'l yopiq. Exit code ham shunday: 0 — "yetkazildi", boshqa sonlar — har xil "yetkazilmadi".

2.2 Nega muvaffaqiyat — 0?

Boshida g'alati tuyulishi mumkin: odatda 0 "yomon", "hech narsa" degan ma'noda keladi. Maktabda 0 baho olish yaxshi emas.

Sababi yuqoridagi o'xshatishda. Muvaffaqiyatning bitta turi bor, xatoning esa ko'p turi. Bitta holatga bitta son — 0 — yetadi. Qolgan 255 ta son har xil xatolarni ajratish uchun qoldirilgan. Dastur "xato bo'ldi" deyish bilan birga "qanday xato" ekanini ham aytishi mumkin.

Maslahat: Keyinroq JavaScript'da 0 "yolg'on" (false) deb qaralishini ko'rasiz. Exit code'da esa 0 — muvaffaqiyat. Bu ikki xil dunyo, ular bir-biriga zid emas: bu yerda 0 — "xatolar soni nol" deb o'ylang.

2.3 $? — oxirgi buyruqning kodi

Exit code ekranga chiqmaydi — shell uni jimgina $? degan maxsus o'zgaruvchida saqlaydi. O'zgaruvchi — nom berilgan qiymat saqlanadigan joy. $ belgisi shell'ga "shu nomdagi qiymatni qo'y" deydi. O'zgaruvchilarni keyingi darsda to'liq o'rganamiz; hozir $? ni tayyor "savol" deb biling: "oxirgi buyruq qanday tugadi?"

Git Bash, WSL yoki macOS terminalini oching va sinab ko'ring:

bash
mkdir -p kod-mashq
cd kod-mashq
touch bor.txt
ls bor.txt
echo $?
text
bor.txt
0

ls faylni topdi va 0 qaytardi. Endi yo'q faylni so'raymiz:

bash
ls yoq.txt
echo $?
text
ls: cannot access 'yoq.txt': No such file or directory
2

Kod — 2. ls ning qo'llanmasida (man ls) yozilgan: 2 — "jiddiy muammo", masalan, fayl topilmadi.

Diqqat: $? faqat eng oxirgi buyruqni eslaydi. echo $? ni ikki marta yozsangiz, ikkinchisi 0 ko'rsatadi — chunki endi "oxirgi buyruq" birinchi echo edi va u muvaffaqiyatli tugagan. Kodni tekshirish kerak bo'lsa, buyruqdan darhol keyin qarang.

Tekshirib ko'ring: Quyidagidan keyin ekranda qaysi sonlar chiqadi?

bash
ls yoq.txt
echo $?
echo $?
Javob

Avval xato matni, keyin 2, keyin 0. Birinchi echo $? ls ning kodini ko'rsatdi. Ikkinchi echo $? esa birinchi echo ning kodini ko'rsatdi — u muvaffaqiyatli ishlagan, shuning uchun 0.

3. Ko'p uchraydigan kodlar

3.1 Jadval

Har dastur o'z kodlarini o'zi tanlaydi, lekin ba'zilari deyarli hamma joyda bir xil:

Kod Qachon Misol
0 Hammasi yaxshi ls bor.txt
1 Umumiy xato mkdir mavjud papkaga
2 Noto'g'ri ishlatish yoki jiddiy muammo ls yoq.txt
126 Fayl bor, lekin ishga tushirib bo'lmaydi x huquqisiz skript (Linux, macOS)
127 Buyruq topilmadi salomlar
130 Ctrl + C bilan to'xtatildi uzoq ishlayotgan buyruq

127 ni dastur o'rnatish darsidan taniysiz: command not found ("PATH'dagi papkalarda topilmadi") xatosi aynan shu kodni beradi.

Kodni kim tanlaydi? Dasturni yozgan dasturchi. U dastur oxirida "qaysi son bilan chiqish kerak"ligini yozib qo'yadi: bash skriptda — exit 1, Node.js'da — process.exit(1). Ikkalasini ham keyinroq o'zingiz yozasiz (shell skript darsida — birinchisini). Shuning uchun kodlarning aniq ma'nosi dasturning qo'llanmasida (--help, man) yoziladi.

bash
mkdir loyiha
mkdir loyiha
echo $?
text
mkdir: cannot create directory 'loyiha': File exists
1

Birinchi mkdir papkani yaratdi (0). Ikkinchisi "papka allaqachon bor" dedi va 1 qaytardi.

3.2 grep ning alohida qoidasi

grep uchun kodlar bir oz boshqacha ma'noga ega:

grep kodi Ma'nosi
0 So'z topildi
1 So'z topilmadi (bu xato emas!)
2 Haqiqiy xato: masalan, fayl yo'q
bash
grep "Toshkent" bor.txt
echo $?
text
1

bor.txt bo'sh, so'z topilmadi. Ekranda hech qanday xato matni yo'q — lekin kod 1. Bu "topilmadi" degani, xato emas. Bu farq zanjirlarda muhim bo'ladi.

3.3 true va false

Mashq uchun ikkita maxsus buyruq bor. true hech narsa qilmaydi va doim 0 qaytaradi. false ham hech narsa qilmaydi, lekin doim 1 qaytaradi. Ular zanjirlarni sinab ko'rish uchun qulay.

bash
false
echo $?
text
1

Tekshirib ko'ring: Siz nodee --version deb yozdingiz (bitta ortiqcha e). echo $? qaysi sonni ko'rsatadi?

Javob

127 — "buyruq topilmadi". Shell PATH'dagi papkalardan nodee degan dasturni qidirdi va topmadi. Ekranda bash: nodee: command not found chiqadi.

4. Buyruqlarni zanjirlash

Bir nechta buyruqni bitta qatorda yozish mumkin. Ular orasiga qanday belgi qo'yilsa, shunday qoida bilan bajariladi.

4.1 ; — "baribir davom et"

bash
ls yoq.txt ; echo "baribir ishladi"
text
ls: cannot access 'yoq.txt': No such file or directory
baribir ishladi

; — oddiy ajratgich. U oldingi buyruq qanday tugaganiga qaramaydi. Xuddi ikki buyruqni alohida qatorlarda yozgandek.

4.2 && — "faqat muvaffaqiyatli bo'lsa"

bash
ls bor.txt && echo "fayl topildi"
text
bor.txt
fayl topildi
bash
ls yoq.txt && echo "fayl topildi"
text
ls: cannot access 'yoq.txt': No such file or directory

Ikkinchi holatda echo umuman ishlamadi. && ("va") qoidasi: chapdagi buyruq 0 qaytarsa — o'ngdagisi ishlaydi. Boshqa son qaytarsa — o'ngdagisi o'tkazib yuboriladi.

Hayotdan: "Imtihondan o'tsang, va keyin tatilga borasan". Imtihondan o'tmasangiz — tatil yo'q.

Zanjir uzun bo'lishi mumkin. Bittasi yiqilsa, qolganlari to'xtaydi:

bash
mkdir -p sayt && cd sayt && touch index.html

Papka yaratildimi — kiramiz. Kirdikmi — fayl yaratamiz. Agar cd biror sabab bilan ishlamasa, touch noto'g'ri papkada fayl yaratmaydi.

4.3 || — "faqat xato bo'lsa"

bash
ls yoq.txt || echo "fayl yo'q ekan"
text
ls: cannot access 'yoq.txt': No such file or directory
fayl yo'q ekan

|| ("yoki") — && ning teskarisi. Chapdagi buyruq xato bilan tugasa (0 emas) — o'ngdagisi ishlaydi. Muvaffaqiyatli bo'lsa — o'tkazib yuboriladi.

Hayotdan: "Avtobusga ulgur, yoki taksi chaqir". Avtobusga ulgursangiz, taksi kerak emas.

| (pipe) va || ni adashtirmang: bittasi natijani uzatadi, ikkitasi — "xato bo'lsa" degani.

4.4 Uchalasi bir rasmda

flowchart TD
  A["1-buyruq bajariladi"] --> B{"Exit code 0 mi?"}
  B -- "ha, 0" --> C["&& dan keyingisi ishlaydi<br/>|| dan keyingisi o'tkaziladi"]
  B -- "yo'q, 1..255" --> D["|| dan keyingisi ishlaydi<br/>&& dan keyingisi o'tkaziladi"]
  A -.-> E["; dan keyingisi<br/>har doim ishlaydi"]
Belgi Ikkinchi buyruq qachon ishlaydi Hayotiy ma'nosi
; Har doim "keyin"
&& Birinchisi 0 qaytarsa "muvaffaqiyatli bo'lsa, keyin"
|| Birinchisi 0 dan boshqa qaytarsa "xato bo'lsa, unda"

Tekshirib ko'ring: Qaysi so'z ekranga chiqadi?

bash
false && echo "A"
false || echo "B"
true ; echo "C"
Javob

B va C. false doim 1 qaytaradi: && dan keyingi A o'tkazib yuboriladi, || dan keyingi B ishlaydi. ; esa kodga qaramaydi — C doim chiqadi.

4.5 && va || birga: tuzoq bilan

Ko'pincha shunday yoziladi: "muvaffaqiyat bo'lsa — bir xabar, bo'lmasa — boshqa":

bash
ls bor.txt && echo "bor" || echo "yo'q"
text
bor.txt
bor

Bu ko'pincha ishlaydi, lekin bu haqiqiy "agar–aks holda" emas. || o'zidan oldingi hamma narsaning natijasiga qaraydi — ya'ni echo "bor" ga ham. Agar o'rtadagi buyruq xato bersa, oxirgisi ham ishlab ketadi:

bash
true && false || echo "bu ham ishladi"
text
bu ham ishladi

Birinchisi muvaffaqiyatli edi, lekin o'rtadagi false yiqildi — va || ishga tushdi. Oddiy xabarlar uchun bu zararsiz. Muhim ishlarda esa haqiqiy if ishlatiladi — uni shell skript darsida o'rganamiz.

5. Pipe'ning exit code'i

Pipe bilan ulangan zanjirda $? faqat oxirgi buyruqning kodini ko'rsatadi:

bash
ls yoq.txt | wc -l
echo $?
text
ls: cannot access 'yoq.txt': No such file or directory
0
0

ls yiqildi (2), lekin wc -l muvaffaqiyatli sanadi (0 qator) — va butun zanjir 0 deb hisoblandi. Bu xavfli bo'lishi mumkin: xato "yutib yuboriladi". Bash'da buni o'zgartiradigan sozlama bor — set -o pipefail. U yoqilsa, zanjirning birorta bo'lagi yiqilsa, butun zanjir xato hisoblanadi. Uni skriptlar darsida ishlatamiz.

6. CI: exit code'ning asosiy ishi

Katta kompaniyalarda kodni hech kim qo'lda serverga chiqarmaydi. Buni CI (Continuous Integration — uzluksiz birlashtirish) tizimi qiladi. U har safar kodga o'zgarish kiritilganda buyruqlarni avtomatik bajaradi. Eng mashhurlaridan biri — GitHub Actions, uni Git qismida sozlaymiz.

CI ekrandagi yozuvlarni o'qimaydi. U faqat exit code'ga qaraydi:

  • Har bir buyruq 0 qaytarsa — yashil belgi , keyingi qadam boshlanadi.
  • Birorta buyruq 0 dan boshqa qaytarsa — qizil belgi , jarayon to'xtaydi, dasturchiga xabar keladi.

Masalan, testlarni ishga tushiradigan dastur bitta test yiqilsa ham 1 qaytaradi. npm test shunday buyruqlardan biri (npm — JavaScript loyihalari vositasi, keyinroq o'rganamiz). Shu bitta raqam buzilgan kodni foydalanuvchilarga yetkazmaydi.

Siz o'zingiz ham har kuni shu g'oyani ishlatasiz:

bash
npm test && npm run build

"Testlar o'tsa — keyin loyihani yig'". Bu qatorni real loyihalarning README fayllarida ko'p uchratasiz. README — loyiha papkasidagi "meni o'qi" nomli yo'riqnoma fayli: loyiha nima va uni qanday ishga tushirish yozilgan bo'ladi.

7. PowerShell'da qanday?

PowerShell'da exit code bilan ishlash biroz boshqacha:

Vazifa bash PowerShell
Oxirgi dastur kodi $? (son) $LASTEXITCODE (son)
"Muvaffaqiyatli bo'ldimi?" $? = 0 $? = True yoki False
&& va || Ishlaydi Faqat PowerShell 7 dan boshlab

Windows'da tayyor keladigan Windows PowerShell 5.1 da && yozsangiz, shunday xato chiqadi:

text
The token '&&' is not a valid statement separator in this version.

"&& belgisi bu versiyada buyruqlarni ajratuvchi emas". Buyruq to'g'ri — versiya eski. Ikki yechim bor: Git Bash'dan foydalanish yoki PowerShell 7 ni o'rnatish. Batafsil — PowerShell darsida.

8. Ko'p uchraydigan xatolar

8.1 && o'rniga ; yozish

bash
npm test ; npm run deploy

Testlar yiqildi — lekin ; bunga qaramaydi va buzilgan kod serverga chiqib ketdi. Xato xabari ekranda ko'rindi, lekin juda kech. Qoida: keyingi buyruq oldingisining natijasiga bog'liq bo'lsa — doim &&.

8.2 $? ni kechikib tekshirish

bash
ls yoq.txt
echo "tekshiryapman..."
echo $?
text
ls: cannot access 'yoq.txt': No such file or directory
tekshiryapman...
0

0 chiqdi — lekin bu ls ning emas, o'rtadagi echo ning kodi. Qoida: $? ni buyruqdan darhol keyin o'qing.

8.3 grep ning 1 ini xato deb o'ylash

grep "TODO" app.js && echo "Eslatmalar bor" — so'z topilmasa, echo ishlamaydi. Bu to'g'ri xatti-harakat: 1 — "topilmadi". Lekin boshlovchilar buni "grep buzildi" deb o'ylaydi. Kod 2 bo'lsa — haqiqiy xato (masalan, fayl yo'q).

8.4 cd yiqilgani sezilmay qolishi

bash
cd yoqpapka ; touch hisobot.txt
text
bash: cd: yoqpapka: No such file or directory

cd yiqildi, lekin ; tufayli touch baribir ishladi — va faylni noto'g'ri papkada (siz turgan joyda) yaratdi. touch o'rnida o'chirish buyrug'i bo'lsa, oqibati jiddiy bo'lardi. Tuzatish: cd yoqpapka && touch hisobot.txt.

9. Mashqlar

Mashqlarni kod-mashq papkasida bajaring.

1-mashq (oson): Kodni toping

Har bir buyruqdan keyin echo $? ni ishga tushirsangiz, qaysi son chiqadi? Avval o'ylang, keyin tekshiring.

  • ls bor.txt →
  • ls yoq.txt →
  • salom (bunday buyruq yo'q) →
  • false →
Yechim
  • ls bor.txt — fayl bor, 0.
  • ls yoq.txt — fayl yo'q, ls bu holatda 2 qaytaradi.
  • salom — command not found, kod 127.
  • false — doim 1.

2-mashq (o'rta): Zanjir tuzing

Bitta qator bilan quyidagini qiling: hisobot papkasini yarating, unga kiring va ichida yanvar.txt faylini yarating. Har bir qadam faqat oldingisi muvaffaqiyatli bo'lsagina bajarilsin.

Keyin ikkinchi qator yozing: agar fevral.txt fayli bo'lmasa, ekranga Fevral hisoboti hali yo'q deb chiqsin.

Yechim
bash
mkdir -p hisobot && cd hisobot && touch yanvar.txt
ls fevral.txt || echo "Fevral hisoboti hali yo'q"
text
ls: cannot access 'fevral.txt': No such file or directory
Fevral hisoboti hali yo'q

Birinchi qatorda &&: har qadam oldingisiga bog'liq. mkdir -p papka bor bo'lsa ham xato bermaydi — shuning uchun zanjir ikkinchi marta ishga tushirilganda ham buzilmaydi.

Ikkinchi qatorda ||: ls yiqilsa — xabar chiqadi. Xato matnini yashirish uchun 2> /dev/null qo'shsa bo'ladi: ls fevral.txt 2> /dev/null || echo "...".

3-mashq (qiyin): Tergov

Jasur shunday yozdi va hayron bo'ldi:

bash
grep "narx" yoq.js | wc -l && echo "narx topildi"
text
grep: yoq.js: No such file or directory
0
narx topildi

"Fayl yo'q-ku, nega narx topildi chiqdi?" Sababini tushuntiring va to'g'ri variantini yozing: xabar faqat narx so'zi haqiqatan topilganda chiqsin.

Yechim

&& pipe zanjirining exit code'iga qaraydi, u esa oxirgi buyruqniki — wc -l. wc bo'sh kirishni muvaffaqiyatli sanadi (0 qator) va 0 kodini qaytardi. grep ning 2 kodi yutib yuborildi.

To'g'risi — grep ning o'z kodiga qarash. Sanash kerak bo'lmasa, pipe'ni olib tashlaymiz:

bash
grep "narx" yoq.js && echo "narx topildi"

Endi grep 2 qaytaradi (fayl yo'q) yoki 1 (so'z yo'q) — ikkalasida ham xabar chiqmaydi. So'z topilsa (0) — topilgan qator va narx topildi chiqadi.

10. Real ishda

  • README yo'riqnomalari. npm install && npm run dev — "o'rnatish muvaffaqiyatli bo'lsa, ishga tushir". Deyarli har bir JavaScript loyihasida shunday qator bor.
  • CI. GitHub Actions, GitLab CI — hammasi buyruqlarning exit code'iga qarab yashil yoki qizil bo'ladi.
  • Deploy skriptlari. git pull && npm ci && npm run build && pm2 restart app — har bir bo'g'in oldingisiga bog'liq. Nomlarning ko'pi sizga hali notanish — ularni kursda bittalab o'rganamiz.
  • Tekshirish buyruqlari. command -v node || echo "Node o'rnatilmagan" — dastur bor-yo'qligini tekshirish.
  • Intervyu. "Exit code 0 nima degani?", "&& va ; farqi?", "127 qanday xato?" — Linux va DevOps bo'yicha tez-tez so'raladi.

Xulosa

  • Exit code — dastur tugaganda qaytaradigan son: 0 — muvaffaqiyat, 1–255 — xato.
  • echo $? oxirgi buyruqning kodini ko'rsatadi — buyruqdan darhol keyin o'qing.
  • Tanish kodlar: 1 — umumiy xato, 2 — jiddiy muammo, 127 — buyruq topilmadi, 130 — Ctrl + C.
  • ; — har doim, && — faqat muvaffaqiyatda, || — faqat xatoda.
  • Pipe'da $? faqat oxirgi buyruqniki; grep ning 1 i — "topilmadi", xato emas.
  • CI tizimlari aynan exit code'ga qarab kodni o'tkazadi yoki to'xtatadi.

Keyingi dars: Muhit o'zgaruvchilari, PATH va shell sozlamalari — $? kabi o'zgaruvchilarni o'zingiz yaratishni, dasturlarga sozlama uzatishni va terminalni o'zingizga moslashni o'rganamiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Exit code va buyruqlarni zanjirlash: $?, && va || — IlmHamroh