🧹 शाळेच्या पद्धतीने shell scripting शिका

प्रत्येक server अजूनही ज्या भाषेत आदेश घेतो ती, शाळेच्या केअरटेकरच्या रूपात शिकवलेली: एका वेळी एक ओळ, एक उत्तर, एक exit code, आणि रात्री घंटा वाजवू शकेल अशा लिहून ठेवलेल्या दिनचर्या. प्रत्येक धडा म्हणजे क्रमांकित आकृती असलेली शाळेची गोष्ट — आणि scripts रेपोच्या आतच आहेत: नोंदवहीचे साधन, lock आणि rotation असलेला रात्रीचा backup, आणि साध्या bash मध्ये लिहिलेला test runner.

🧹 commands🗺️ paths & rwx🔀 pipes✂️ grep sed awk🏷️ quoting🔁 loops🚨 set -euo pipefail🔔 cron🔬 shellcheck

🧹 भाग 1 — केअरटेकरचा आवाज (1–6)

  • एक command, एक उत्तर, एक exit code 🧹
  • इमारतीचा नकाशा आणि कोणत्या खोलीत कोण जाऊ शकते 🗺️
  • कॉरिडॉर: pipes, stdout, stderr 🔀
  • ऑफिस: grep, sed, awk ✂️
  • नावाच्या पट्ट्या आणि quoting चा नियम 🏷️
  • exit codes वरून निर्णय आणि loops 🔁

🌙 भाग 2 — रात्रपाळी (7–12)

  • arguments आणि main असलेल्या दिनचर्या 🧩
  • आगीची तालीम: strict mode, trap, dry runs 🚨
  • इमारतीत कोण आहे: processes आणि signals 👥
  • घंटा: cron, locks, idempotent runs 🔔
  • मेलरूम आणि container: CI, entrypoints, गुपिते 📮
  • पाहणे आणि तपासणे: bash -x, shellcheck, एक test runner 🔬
# the 60-second wow — real scripts, no installs:
git clone https://github.com/BaluRaut/learn-shell-school.git && cd learn-shell-school
bin/school.sh list                 # the register, from a CSV, through sort and column
bash bin/smoke_test.sh             # every lesson's idea, proven on the real scripts
bash tests/run_tests.sh            # 14 checks in ~30 lines of bash

तुम्हाला काय दिसायला हवे (छाटलेले — यश असे दिसते):

── L01 · a command, its arguments, its exit code
name       class  grade
Aishwarya  3A     A
Dipika     3A     B+
Katrina    3A     A+
exit code: 0

── L03 · the report to stdout, the log to stderr — they never mix
(stdout was empty; the log went to stderr)
   stderr: HH:MM:SS [school] already enrolled: Zoya (idempotent — nothing changed)

── L04 · pipes: grep | sort | awk
Aishwarya Dipika Katrina Meera Rohan Zoya 

── L05 · a variable with a default, overridden by the environment
   SCHOOL_REGISTER=/tmp/xxxx

── L06 · a bad class is refused with exit 1
   HH:MM:SS [school] ERROR: class must be one of: 3A 3B
   exit code: 1

── L07 · sub-commands and --help
   The school register as a command-line tool — the whole course in one script. (Lessons 01–12)
   
   bin/school.sh list [--class 3A]        the register, optionally one class

── L08 · set -u catches a typo
   bash: REGISTR: unbound variable

── L09 · a background job and wait
   the bell rang
   (waited for it)

── L10 · the backup, dry run first
   HH:MM:SS [backup] would: tar -czf /tmp/xxxx -C /tmp/xxxx tmp.4mpnRnOd5V
   HH:MM:SS [backup] done

── L11 · the same script, run by cron / CI / a container: no terminal, no prompt, exit code is the contract
   backup exit code: 0

── L12 · the tests
14 passed, 0 failed

🎉 the caretaker's routine runs
🎒 धडा 01 आधी: तुम्हाला bash (macOS, Linux, किंवा Windows वर WSL) आणि terminal लागतो — काहीच install करायचे नाही. चांगले शेजारी: CI/CD शाळा (जिथे या scripts प्रत्येक push वर चालतात), Docker शाळा (entrypoints म्हणजे धडा 11) आणि Networking शाळा (curl, dig आणि nc ही shell ची साधनेच). हे काय नाही: Linux administration चा कोर्स — package managers नाहीत, timers पलीकडे systemd नाही; डेव्हलपर किंवा SRE दर आठवड्याला लिहितो ती scripting.

🗺️ संपूर्ण चित्र — एक आकृती, पूर्ण कोर्स

संपूर्ण कोर्स एका कॅनव्हासवर. 4K आवृत्तीसाठी क्लिक करा.

The big picture: the caretaker's voice (commands, paths, pipes, text tools, quoting, loops) and the night shift (functions, safety, processes, cron, CI, testing)

🧹 भाग 1 — केअरटेकरचा आवाज (धडे 1–6)

एक git ब्रँच = एक कल्पना; ब्रँच 04 मध्ये धडे 01–04 आहेत. लॅब macOS, Linux किंवा WSL वरच्या कोणत्याही bash मध्ये चालतात.

1

🧹 Shell का

केअरटेकरचा आवाज — एक command, तिचे arguments, तिचे उत्तर आणि तिचा exit code; प्रत्येक server अजूनही ती का बोलतो.lesson-01-why-the-shellधडा वाचा →आकृती पहा ↗
2

🗺️ फाइल्स, paths & परवानग्या

इमारतीचा नकाशा — absolute आणि relative paths, लपलेल्या फाइल्स, आणि rwx: कोणत्या खोलीत कोण जाऊ शकते.lesson-02-files-and-pathsधडा वाचा →आकृती पहा ↗
3

🔀 Pipes & redirection

कॉरिडॉर — stdin, stdout, stderr; | · > · >> · 2>&1 · tee; अहवाल आणि नोंदवही कधीच मिसळत नाहीत.lesson-03-pipes-redirectionधडा वाचा →आकृती पहा ↗
4

✂️ मजकुराची साधने

ऑफिस — grep, sed, awk, cut, sort, uniq, wc, tr: CSV म्हणून नोंदवही, आणि प्रश्नांची उत्तरे देणाऱ्या एक-ओळी.lesson-04-text-toolsधडा वाचा →आकृती पहा ↗
5

🏷️ Variables & quoting

नावाच्या पट्ट्या — $VAR, "$VAR", ${VAR:-default}, $(command); quotes नसलेली variables ही पहिल्या क्रमांकाची चूक का.lesson-05-variables-quotingधडा वाचा →आकृती पहा ↗
6

🔁 अटी & loops

केअरटेकरचे निर्णय — exit codes, if आणि [[ ]], case, for आणि while, && आणि ||.lesson-06-conditions-loopsधडा वाचा →आकृती पहा ↗

🌙 भाग 2 — रात्रपाळी (धडे 7–12)

पहाटे 2 वाजता कोणी नसताना चालायला आणि विश्वासार्ह असायला script ला लागणारे सगळे, प्रत्येक तुकडा त्याच दोन scripts वर दाखवलेला.

7

🧩 Functions & arguments

पुन्हा वापरता येणाऱ्या दिनचर्या — functions, $1 $@ $#, local, एक main, sub-commands, header comment मधून --help.lesson-07-functions-argumentsधडा वाचा →आकृती पहा ↗
8

🚨 चुका & सुरक्षितता

आगीची तालीम — set -euo pipefail, trap, mktemp, dry runs, shellcheck; मोठ्याने नापास होणारी आणि आवरून घेणारी script.lesson-08-errors-safetyधडा वाचा →आकृती पहा ↗
9

👥 Processes & jobs

इमारतीत कोण आहे — ps, kill आणि signals, & आणि wait, jobs, nohup, xargs -P; PID 1 आणि zombies.lesson-09-processes-jobsधडा वाचा →आकृती पहा ↗
10

🔔 वेळापत्रक & automation

घंटा — cron, systemd timers, lock फाइल्स, logs, idempotent runs; एकाच वेळी दोनदा कधीच न चालणारा रात्रीचा backup.lesson-10-schedulingधडा वाचा →आकृती पहा ↗
11

📮 CI & containers मधल्या scripts

मेलरूममधला केअरटेकर — shebangs, bash विरुद्ध POSIX sh, entrypoints, env आणि गुपिते, करार म्हणून exit codes.lesson-11-ci-and-containersधडा वाचा →आकृती पहा ↗
12

🔬 Debugging & testing

bash -x, PS4, shellcheck, ~30 ओळींच्या bash मधला test runner — आणि कळस-प्रकल्प: backup, तपासलेला.lesson-12-debugging-testingधडा वाचा →आकृती पहा ↗
🗣️ मोठ्याने समजावा — धडा 12 नंतर: (1) अहवाल stdout वर आणि नोंदवही stderr वर का असावी — ते मिसळले तर काय मोडते? (2) "$name" विरुद्ध $name: दुसऱ्याने चुकीची फाइल पुसावी असा नेमका input द्या. (3) set -e, -u आणि -o pipefail प्रत्येक काय पकडते, आणि set -e काय पकडत नाही? (4) cron job "हाताने चालवली की चालते" — तुमच्या shell आणि cron च्या shell मधले तीन फरक सांगा. (5) चांगला entrypoint exec "$@" ने का संपतो? (6) काल रात्री backup एकाच वेळी दोनदा चालला — backup.sh च्या कोणत्या दोन ओळींनी ते थांबवले असते?
🎓 याच शाळेतून: CI/CD · Docker · Networking · Database — तेच उपमांचे विश्व, तीच ब्रँच-मागून-ब्रँच पद्धत.

📐 धड्यांच्या आकृत्या — क्रमांक अनुसरा

प्रत्येक धडा एका क्रमांकित बॉक्स-आणि-बाण आकृतीत — स्वतंत्र पानावरही.

1 🧹 Shell का

केअरटेकरचा आवाज — एक command, तिचे arguments, तिचे उत्तर आणि तिचा exit code; प्रत्येक server अजूनही ती का बोलतो.

🧒 सोप्या शब्दांत

कल्पना करा, तुम्ही शाळेच्या caretaker ला एक ओळ सांगता: 'वर्ग 3A ची यादी दाखवा'. तो यादी वाचून दाखवतो आणि मग एक आकडा दाखवतो: सगळे ठीक झाले तर 0, काही चुकले तर दुसरा आकडा. computer साठी shell हाच caretaker आहे. प्रत्येक server आणि CI robot अजूनही असेच आदेश घेतो, म्हणून याच ओळी script मध्ये साठवून उद्या पुन्हा चालवता येतात.

📖 नवे शब्दcommand — तुम्ही सांगितलेल्या कामाचे नाव, उदा. listflag — command ने काम कसे करावे हे सांगणारी जादा माहिती, उदा. --class 3Aexit code — शेवटी दाखवलेला आकडा: 0 म्हणजे ठीक, 1 ते 255 म्हणजे काहीतरी fail झालेscript — पुन्हा पुन्हा चालवता याव्यात म्हणून file मध्ये लिहिलेल्या shell च्या ओळी
1🧹 केअरटेकर एक ओळ ऐकतो, उत्तर देतो, आणि एक आकडा दाखवतोbin/school.shlist--class3Acommandsub-commandflag आणि तिचे मूल्य$ bin/school.sh list --class 3Aname class grade ← stdout: अहवालAishwarya 3A ADipika 3A B+[school] listed 2 students ← stderr: नोंदवही$ echo $? → 0 ← exit codescript म्हणजे तेच आदेश लिहून ठेवलेले · प्रत्येक server, container आणि CI runner अजूनही असेच आदेश घेतो2🔢 exit code — प्रत्येक साधनाला समजणारा एकच शब्द0ठीक ✓1 … 255नाही ✗&& and ||ठीक असेल तरच पुढची पायरीcronअपयशावर mailCIcommit वर हिरवा ✓ किंवा लाल ✗Dockercontainer पुन्हा सुरू$? मध्ये शेवटचे उत्तर · true = 0 · false = 13🏫 केअरटेकर कुठे काम करतो — सगळीकडे तोच आवाजतुमचा terminalserver (ssh)🐳 containerentrypoint⚙️ CI runnerjob ची पायरी#!/usr/bin/env bashset -euo pipefailbin/school.sh report# exit 0 → पायरी हिरवीबहुतेक Linux वर bash ही बोली; sh जुनी सामाईक भाषा · man cmd आणि cmd --help म्हणजे सूचना फलक
⏪ आधी

shell शिवाय तुम्ही एकेक screen वर click करत बसता, आणि केलेले काम पुन्हा चालवता, script करता किंवा तपासता येत नाही.

💡 काय

shell म्हणजे एक ओळ ऐकणारा caretaker: command, त्याचे arguments आणि flags, आणि उत्तर म्हणून output व exit code.

⚙️ कसे

तुम्ही bin/school.sh list --class 3A टाइप करता; report stdout वर, log stderr वर जातो, आणि echo $? exit code 0 दाखवतो.

🎯 का

प्रत्येक server, container आणि CI runner अजूनही असेच आदेश घेतो; exit code 0 म्हणजे ठीक, 1 ते 255 म्हणजे नाही.

🚀 पुढे

पुढे तुम्ही इमारतीचा नकाशा शिकाल: files, paths आणि permissions, ज्यांना तुमचा प्रत्येक command स्पर्श करतो.

🧪 Try it here — केअरटेकरला आदेश द्या आणि तीन उत्तरे वाचा: अहवाल, नोंदवही, exit code

संपूर्ण धडा 01 वाचा →

2 🗺️ फाइल्स, paths & परवानग्या

इमारतीचा नकाशा — absolute आणि relative paths, लपलेल्या फाइल्स, आणि rwx: कोणत्या खोलीत कोण जाऊ शकते.

🧒 सोप्या शब्दांत

फक्त 'खोली 5' म्हटले तर पाहुणा हरवू शकतो, पण पूर्ण पत्ता कुठूनही चालतो. प्रत्येक file ला असा पत्ता असतो, उदा. /home/you/school/data/register.csv. प्रत्येक खोलीला तीन प्रकारच्या चाव्या असतात: वाचणे, लिहिणे आणि आत जाणे. owner, group आणि बाकी सगळे यांना त्या वेगवेगळ्या दिल्या जातात, म्हणून तुमच्या गुप्त files तुमच्याच राहतात.

📖 नवे शब्दabsolute path — / पासून सुरू होणारा पूर्ण पत्ता; कोणत्याही folder मधून चालतोrelative path — तुम्ही आत्ता ज्या folder मध्ये आहात तिथून दिशा, उदा. data/register.csvrwx — read, write, execute: पाहणे, बदलणे, किंवा चालवणे (folder साठी आत जाणे)chmod — कोणाकडे कोणती चावी हे बदलणारा command; 600 म्हणजे फक्त तुम्ही
1🗺️ इमारतीचा नकाशा — प्रत्येक फाइलला एक absolute पत्ता📁 /📁 home📁 you📁 school ★ इथे📁 bin📁 data📁 lib📄 school.sh📄 register.csv📄 log.shabsolute: /home/you/school/data/register.csv2🔑 rwx — कोणत्या खोलीत कोण जाऊ शकते-rwxr-x---मालक (तुम्ही): rwxगट: r-xइतर: ---प्रकार7rwx = 4+2+15r-x = 4+0+10--- = 0modeकशासाठी755scripts आणि folders644साध्या फाइल्स600गुपिते (फक्त तुम्ही)777कधीच नाही — सगळी दारे उघडीchmod +x script.shchmod 600 secret.envchown who:group file3📍 HERE — script ला कुठून बोलावले याची पर्वा नसावी$ cd /home/you$ school/bin/school.sh listHERE=/home/you/school/bin ✓$ cd /tmp$ /home/you/school/bin/school.sh listHERE=/home/you/school/bin ✓HERE="$(cd "$(dirname "$0")" && pwd)"कुठूनही तेच उत्तरप्रत्येक path त्यावर बांधा:"$HERE/../data/register.csv"~ घर · . इथे · .. वर · * SHELL विस्तारते तो wildcard · /etc config · /var/log logs · /tmp कच्चे काम · /proc इमारतीचा स्वतःचा dashboard
⏪ आधी

paths आणि permissions शिवाय file नीट सापडत नाही, आणि कोणीही तुमची secrets वाचू किंवा scripts बदलू शकतो.

💡 काय

प्रत्येक file चा / पासून एकच absolute पत्ता असतो, आणि rwx bits ठरवतात की कोण वाचू, लिहू किंवा खोलीत जाऊ शकतो.

⚙️ कसे

Mode 755 म्हणजे owner ला rwx (4+2+1=7) आणि group व others ला r-x (5); chmod 600 secret.env फक्त तुमच्यासाठी ठेवतो.

🎯 का

योग्य permissions अपघात आणि leaks थांबवतात: साध्या files ला 644, scripts ला 755, आणि सर्व दारे उघडी असलेले 777 कधीच नाही.

🚀 पुढे

HERE ठरवल्यावर script कोणत्याही folder मधून चालते; पुढच्या lessons मधील pipes आणि tools चा हाच पाया आहे.

🧪 Try it here — दारे टिक करा, mode वाचा — मग एका folder मधून relative path सोडवा

संपूर्ण धडा 02 वाचा →

3 🔀 Pipes & redirection

कॉरिडॉर — stdin, stdout, stderr; | · > · >> · 2>&1 · tee; अहवाल आणि नोंदवही कधीच मिसळत नाहीत.

🧒 सोप्या शब्दांत

शाळेच्या corridor मधील relay race आठवा: प्रत्येक धावपटू पुढच्याला baton देतो. shell मध्ये | हे चिन्ह एका command चा report पुढच्या command ला देते. प्रत्येक command ला आत येण्याचे एक दार आणि बाहेर जाण्याची दोन दारे असतात: एक स्वच्छ report साठी, एक तक्रारींसाठी. म्हणून पुढच्या धावपटूला फक्त स्वच्छ data मिळतो. चार छोटे commands मिळून '3A मध्ये किती मुले?' याचे उत्तर देतात.

📖 नवे शब्दstdin — दार 0: आत येणारे, keyboard मधून किंवा आधीच्या command कडूनstdout — दार 1: स्वच्छ reportstderr — दार 2: log आणि तक्रारी, report पासून वेगळ्या ठेवलेल्याpipe (|) — एका command चा report थेट पुढच्या command ला देतो> and >> — report file मध्ये पाठवतात: > file बदलून टाकतो, >> शेवटी जोडतो
1🔀 प्रत्येक command च्या आत आणि बाहेर तीन कॉरिडॉर⌨️keyboard, किंवाआधीचा pipe0stdin⚙️ commandschool.sh list1📄 अहवालनोंदवहीstdout2📣 नोंदवही"enrolled Zoya"stderr0 वाचते · अहवाल 1 वर लिहिते · तक्रारी 2 वर लिहितेअहवाल आणि नोंदवही कधीच मिसळत नाहीत — म्हणून pipe ला स्वच्छ data मिळतो2🚰 pipeline — एकाचा अहवाल पुढच्या command चा inputschool.sh list|6 ओळीgrep 3A|3 ओळीsort|3 ओळीwc -l1 ओळ: 3चार छोटी साधने, एका प्रश्नाचे उत्तर: 3A मध्ये किती विद्यार्थी?प्रत्येक साधन 0 वाचते आणि 1 लिहिते — pipe ला एवढेच लागते3↪️ redirections — प्रत्येक कॉरिडॉर कुठे जातो> file📄फाइल च्या जागी अहवाल>> file📄+त्यात जोडा2> errors.txt📣→📄नोंदवही फाइल मध्ये2>&11+2नोंदवही अहवालात मिसळा2>/dev/null🗑️नोंदवही कचऱ्यात| tee file📄 & |फाइल मध्ये आणि पुढेही< file📄→0फाइल stdin म्हणून द्या<<EOF … EOF📝→0here-doc: script मध्येच लिहिलेला मजकूरlist | grep 3A | sort | wc -l — pipe म्हणजे "|": चार commands, एक ओळ
⏪ आधी

redirection शिवाय reports आणि error messages एकाच screen वर मिसळतात, आणि एका tool चे output दुसरा वापरू शकत नाही.

💡 काय

प्रत्येक command ला तीन corridors असतात: आत येणारा stdin (0), report साठी stdout (1), आणि log साठी stderr (2).

⚙️ कसे

pipe त्यांना जोडतो: school.sh list | grep 3A | sort | wc -l सांगतो 3A मध्ये किती मुले आहेत; > आणि 2>&1 output वळवतात.

🎯 का

report आणि log कधीच मिसळत नसल्याने pipe ला नेहमी स्वच्छ data मिळतो, आणि छोटे tools मिळून मोठी उत्तरे देतात.

🚀 पुढे

पुढे text tools येतात, grep, sed, awk वगैरे, जे pipes ने जोडून तुम्ही कोणत्याही file ला प्रश्न विचारता.

🧪 Try it here — खऱ्या नोंदवहीवर pipeline बांधा आणि ओळी कमी होताना पहा

संपूर्ण धडा 03 वाचा →

4 ✂️ मजकुराची साधने

ऑफिस — grep, sed, awk, cut, sort, uniq, wc, tr: CSV म्हणून नोंदवही, आणि प्रश्नांची उत्तरे देणाऱ्या एक-ओळी.

🧒 सोप्या शब्दांत

शाळेचे register ही साधी text यादी आहे: प्रत्येक ओळीवर नाव, वर्ग आणि grade, स्वल्पविरामाने वेगळे. office कडे छोटे tools आहेत, प्रत्येक एकच काम करतो: एक ओळी शोधतो, एक column कापून काढतो, एक क्रमाने लावतो, एक मोजतो. त्यांना जोडा आणि एकाच ओळीत उत्तर मिळते: '3A मध्ये 3 मुले, 3B मध्ये 2', मोठा program न लिहिता.

📖 नवे शब्दCSV — text म्हणून साठवलेले table: प्रत्येक ओळीत एक row, columns स्वल्पविरामाने वेगळेgrep — तुम्ही सांगितलेला शब्द असलेल्या ओळीच ठेवतोcut — एकच column कापून काढतो, उदा. फक्त वर्गsort | uniq -c — सारख्या ओळी शेजारी आणतो, मग प्रत्येक गट मोजतोsed — प्रत्येक ओळीत text शोधून बदलतो, उदा. 3B ऐवजी 3C
1✂️ नोंदवही म्हणजे CSV — प्रत्येक प्रश्न छोट्या साधनांची pipelinename,class,gradeAishwarya,3A,AKatrina,3A,A+Dipika,3A,B+Meera,3B,ARohan,3B,Bdata/register.csvgrep ",3A,"Aishwarya,3A,AKatrina,3A,A+Dipika,3A,B+cut -d, -f23A3A3Asort | uniq -c3 3Aअख्खी नोंदवही, वर्गानुसार: tail -n +2 register.csv | cut -d, -f2 | sort | uniq -c → 3 3A · 2 3Bwc -l मोजते · head / tail डोकावते · tr -s दाबते · column -t तक्ता बनवते · xargs ओळींचे arguments करतेप्रश्न मोठा होईपर्यंत Python नको — school.sh report म्हणजे एक awk program2🖊️ sed — ओळी बदलाMeera,3B,Ased 's/3B/3C/'Meera,3C,Aflagकाय करते-iफाइल जागच्या जागी बदला-n '2,5p'फक्त ओळी 2–5 छापाs/x/y/gओळीतला प्रत्येक match, फक्त पहिला नाही3🧮 awk — स्तंभ आणि मोजणीKatrina$13A$2A+$3-F, स्वल्पविरामावर तोडतेawk -F, '$3=="A+" {n++} END {print n}'1NR = ओळ क्रमांक · NF = स्तंभ संख्या · END शेवटच्या ओळीनंतर चालतेschool.sh report: वर्गानुसार, किती, किती A सह
⏪ आधी

text tools शिवाय CSV बद्दलच्या प्रत्येक छोट्या प्रश्नासाठी spreadsheet उघडावी लागते किंवा पूर्ण program लिहावा लागतो.

💡 काय

grep, sed, awk, cut, sort, uniq, wc आणि tr हे office चे छोटे tools आहेत; प्रत्येक text च्या ओळींवर एकच काम करतो.

⚙️ कसे

tail -n +2 register.csv | cut -d, -f2 | sort | uniq -c प्रत्येक वर्गातील मुले मोजतो: 3A मध्ये 3 आणि 3B मध्ये 2.

🎯 का

one-liners खरे प्रश्न काही seconds मध्ये सोडवतात; प्रश्न मोठा होईपर्यंत Python ची गरज नाही.

🚀 पुढे

register चा path सारख्या values scripts मध्ये पुन्हा वापरण्यासाठी पुढचा lesson variables आणि quoting आणतो.

🧪 Try it here — grep, awk आणि sed ने नोंदवहीला प्रश्न विचारा

संपूर्ण धडा 04 वाचा →

5 🏷️ Variables & quoting

नावाच्या पट्ट्या — $VAR, "$VAR", ${VAR:-default}, $(command); quotes नसलेली variables ही पहिल्या क्रमांकाची चूक का.

🧒 सोप्या शब्दांत

register चा पूर्ण पत्ता प्रत्येक वेळी लिहिण्याऐवजी तुम्ही त्यावर name tag लावता: REGISTER. आता $REGISTER म्हणजे तो पत्ता. पण Aishwarya Kumar या नावात space आहे, आणि quote चिन्हांशिवाय shell त्याचे दोन लोक करतो: Aishwarya आणि Kumar. double quotes मध्ये ठेवले की ते एकच राहते. हे quotes विसरणे हा shell मधला सर्वात सामान्य bug आहे.

📖 नवे शब्दvariable — value ठेवणारा name tag, उदा. REGISTER=data/register.csv$VAR — tag वर लिहिलेली value वाचा"$VAR" — value एकाच तुकड्यात राहते, त्यात spaces असल्या तरीexport — तुम्ही सुरू केलेल्या scripts ना सुद्धा tag दिसू देतो
1🏷️ variable म्हणजे नावाची पट्टी — export ती मुलांना दाखवतेहा shellREGISTER=data/register.csv$REGISTER or ${REGISTER}वाचायलामूल: bin/school.shexport✓ REGISTER दिसतेexport नाही✗ रिकामे — ऐकलेच नाहीPATH, HOME, USER बाहेरून येतात · REGISTER=… (= भोवती spaces नकोत)2"" quoting चा नियम — "$name" नेहमी एकच argumentname="Aishwarya Kumar"echo "$name"Aishwarya Kumar1 argument ✓echo $nameAishwaryaKumar2 arguments — तुकडे ✗echo '$name'$nameअक्षरशः मजकूर$name = spaces वर तुटते + glob · "$name" = एक argument · '$name' = विस्तारच नाही3💣 आजवरच्या प्रत्येक shell script मधली पहिल्या क्रमांकाची चूक — quotes नसलेली, न ठरवलेली variable$ DIR= # अरेच्चा, रिकामी$ rm -rf $DIR/ # होते: rm -rf /💀 अख्खी इमारत$ rm -rf "${DIR:?must be set}/"bash: DIR: must be set$ echo $? → 1 ✓ चालायला नकारआकारम्हणजे${VAR:-default}VAR रिकामी असेल तर default${VAR:?message}रिकामी असेल तर नकार$(command)command चे output पकडा$((2 + 3))अंकगणित → 5set -u (धडा 08) typo महागात पडण्याआधी पकडते$# किती arguments · $@ सगळे · $? शेवटचा exit code · $$ माझा PID
⏪ आधी

variables शिवाय paths सगळीकडे पुन्हा लिहावे लागतात, आणि space असलेले unquoted नाव गुपचूप दोन arguments मध्ये तुटते.

💡 काय

variable म्हणजे REGISTER=data/register.csv सारखा name tag; $REGISTER ने वाचतात, आणि export तो child scripts ला दाखवतो.

⚙️ कसे

"$name" एकच argument राहतो, $name spaces वर तुटतो आणि glob होतो, आणि '$name' काहीही expand न होता तसाच text राहतो.

🎯 का

unquoted variables हा shell मधला नंबर एकचा bug आहे; नेहमी quote केल्याने चुकीच्या files delete किंवा वाचणे टळते.

🚀 पुढे

values variables मध्ये आल्यावर पुढच्या lesson मध्ये caretaker exit codes, if, case आणि loops वापरून निर्णय घेतो.

🧪 Try it here — मूल्यात spaces घाला आणि प्रत्येक लिखाणाने किती arguments होतात ते पहा

संपूर्ण धडा 05 वाचा →

6 🔁 अटी & loops

केअरटेकरचे निर्णय — exit codes, if आणि [[ ]], case, for आणि while, && आणि ||.

🧒 सोप्या शब्दांत

Zoya चे नाव register मध्ये लिहिण्याआधी caretaker तपासतो: ती आधीच आहे का? तपासणी exit code ने उत्तर देते, आणि 0 म्हणजे होय. होय असेल तर तो म्हणतो 'आधीच enrolled'; नाही तर तिचे नाव जोडतो. loop म्हणजे हजेरी घेण्यासारखे: यादीतील प्रत्येक नावासाठी तेच काम. यामुळे script काम करण्याआधी तपासू शकते.

📖 नवे शब्दif — तपासणीचे उत्तर 0 (म्हणजे होय) असेल तेव्हाच हे करा[[ ]] — प्रश्नाचा डबा: file आहे का? आकडा मोठा आहे का?&& and || — && पुढचे काम फक्त यश मिळाल्यावर चालवतो, || फक्त अपयशावरfor / while — प्रत्येक item साठी, किंवा काहीतरी खरे असेपर्यंत, तेच काम पुन्हा कराcase — शब्द जुळवून एक मार्ग निवडा, उदा. list किंवा enrol
1🔢 केअरटेकर exit codes ने ठरवतो — 0 म्हणजे होgrep -q "^Zoya," register.csvexit code 0?हो → 0"आधीच नोंद आहे"नाही → 1ओळ जोडाcmd && यश-वरcmd || अपयश-वरtrue = 0 · false = 1 · नापास grep हीच false शाखा — booleans ची गरज नाही2🧪 tests आणि casetestविचारते[[ -f file ]]फाइल आहे का?[[ $a == $b ]]तोच मजकूर?[[ $n -gt 3 ]]मोठा आकडा?[[ -z $s ]]रिकामे?[[ " $L " == *" $x "* ]]x यादीत आहे?caselist)enrol)*)[ ] जुनी portable test; [[ ]] bash ची सुरक्षित(आत word splitting नाही) — तरी quote कराcase "$cmd" in list) …;; enrol) …;; *) …;; esac3🔁 loops — फाइल्सवर, ओळींवर, आकड्यांवरfor f in *.csv; do … doneregister.csvbackup.csvold.csvglob खऱ्या फाइल्समध्ये विस्तारतो — ls कधीच parse करू नकाwhile read -r line; do … done < register.csvAishwarya,3A,A ← ओळKatrina,3A,A+Dipika,3A,B+एका वेळी एक ओळ · -r \ ठेवते · IFS= spaces ठेवतेfor i in $(seq 1 10)12345678910continue एक वगळते (5) · break बाकी थांबवते (8–10)school.sh मधली valid_class() म्हणजे एक [[ ]] ओळ: [[ " $CLASSES " == *" $1 "* ]]while [[ $# -gt 0 ]] … shift — flags वाचणारा loop (धडा 07)
⏪ आधी

conditions आणि loops शिवाय script तेच steps आंधळेपणाने चालवते, मूल आधीच enrolled असले तरीही.

💡 काय

caretaker exit codes वरून निर्णय घेतो: 0 म्हणजे होय, म्हणून if, &&, ||, case, for आणि while त्यांवरून फाटे घेतात.

⚙️ कसे

Zoya असल्यास grep -q "^Zoya," register.csv 0 देतो; [[ -f file ]] किंवा [[ $n -gt 3 ]] हे tests सुद्धा codes देतात.

🎯 का

booleans लागत नाहीत: fail झालेला grep हाच false branch आहे, त्यामुळे scripts सुरक्षितपणे skip, retry किंवा नकार देऊ शकतात.

🚀 पुढे

निर्णय जमल्यावर पुढचा lesson त्यांना functions आणि list, enrol सारख्या sub-commands मध्ये बांधतो.

🧪 Try it here — test चालवा, तिचा exit code वाचा — मग glob वर loop करा

संपूर्ण धडा 06 वाचा →

7 🧩 Functions & arguments

पुन्हा वापरता येणाऱ्या दिनचर्या — functions, $1 $@ $#, local, एक main, sub-commands, header comment मधून --help.

🧒 सोप्या शब्दांत

caretaker नेहमी करायच्या प्रत्येक कामासाठी एक card ठेवतो: 'मुलांची यादी', 'मुलाचे नाव नोंदवा'. function म्हणजे नाव असलेले असे card: तुम्ही ते बोलावता आणि नाव किंवा वर्ग अशी माहिती देता. school.sh अशाच cards ने बनलेली आहे, आणि एक main card तुम्ही टाइप केलेला पहिला शब्द वाचून योग्य card निवडते. file च्या वरचा comment हाच --help page म्हणूनही काम करतो.

📖 नवे शब्दfunction — नाव असलेला steps चा संच, जो पुन्हा पुन्हा बोलावता येतो$1 $@ $# — दिलेली पहिली माहिती, सगळी माहिती, आणि ती किती आहेlocal — एकाच function च्या आत राहणारा variablesub-command — काम निवडणारा पहिला शब्द, उदा. list किंवा enrol
1📐 खऱ्या script चा आकार — school.sh, वरून खाली#!/usr/bin/env bash# bin/school.sh list [--class 3A] …set -euo pipefailHERE="$(cd "$(dirname "$0")" && pwd)"source "$HERE/../lib/log.sh"REGISTER="${SCHOOL_REGISTER:-…}"usage() { sed -n "2,9p" "$0"; exit; }valid_class() { [[ … ]]; }cmd_list() { … }cmd_enrol() { local n="${1:?}"; … }main() { case "$1" in list) cmd_list "${@:2}";; … esac; }main "$@"← shebang: कोणता केअरटेकर← header = --help (L07)← strict mode (L08)← मी कुठे आहे (L02)← सामाईक log() आणि die()← env बदलू शकणारा default← usage header छापते← test = exit code (L06)← functions: local, ${1:?}← एक case, प्रत्येकी एक दिनचर्या← शेवटची ओळ: main चालवाsource lib/log.sh log() आणि die() scripts मध्ये वाटते · -a -b flags साठी getopts--help वर 0 आणि चुकीच्या वापरावर 1 ने बाहेर पडणारी usage() · तोच सांगाडा 500 ओळींच्या ops साधनापर्यंत जातो2📥 arguments — $1 $2 … "$@" $#school.sh$0enrol$1Zoya$23A$3A$4$# = 4"$@" = enrol Zoya 3A A — प्रत्येक अखंडshift नंतर:Zoya$13A$2A$3$# = 3${1:?enrol needs NAME} — argument नसेल तर सभ्यपणे नकार3🚪 main आणि sub-commands — एक case, अनेक दिनचर्याcase "$cmd" inlist · enrol · gradereport · remove · *esaccmd_listcmd_enrolcmd_gradecmd_reportcmd_removeusage 1 (अनोळखी)local variables आत ठेवते · return 0/1 · मूल्य परत द्यायला echo--help header comment छापते (sed -n 2,9p "$0")
⏪ आधी

functions शिवाय एकच लांब script तोच code पुन्हा पुन्हा लिहिते, आणि ती कोणते arguments घेते हे कोणाला कळत नाही.

💡 काय

function म्हणजे पुन्हा वापरता येणारा routine; त्याचे स्वतःचे arguments $1, $@ आणि $# असतात, आणि local variables खाजगी ठेवतो.

⚙️ कसे

school.sh मध्ये shebang, set -euo pipefail, cmd_list आणि cmd_enrol, आणि main "$@" आहे ज्याचा case sub-command निवडतो.

🎯 का

header comment मधून --help छापणारा खऱ्या script चा आकार वाचायला, test करायला आणि दुसऱ्याला द्यायला सोपा असतो.

🚀 पुढे

पुढे fire drill: strict mode, trap आणि dry runs या script ला मोठ्याने fail करायला आणि स्वतः साफसफाई करायला लावतात.

🧪 Try it here — command line लिहा आणि $0, $1 … "$@" आणि $# वाचा — मग shift

संपूर्ण धडा 07 वाचा →

8 🚨 चुका & सुरक्षितता

आगीची तालीम — set -euo pipefail, trap, mktemp, dry runs, shellcheck; मोठ्याने नापास होणारी आणि आवरून घेणारी script.

🧒 सोप्या शब्दांत

fire drill मध्ये दार बंद असेल तर तुम्ही थांबून हाक मारता, चालत राहत नाही. बेफिकीर script मात्र चालत राहते: 'folder मध्ये जा' fail झाले तर पुढची ओळ 'इथले सगळे delete करा' चुकीच्या files पुसते. set -euo pipefail script ला पहिल्याच अपयशावर थांबवतो, आणि trap म्हणजे काहीही झाले तरी शेवटी दिवे बंद करून कुलूप लावणारे शिक्षक.

📖 नवे शब्दset -e — पहिला command fail झाला की script थांबवाset -u — चुकीचे लिहिलेले किंवा न ठरवलेले variable म्हणजे error, गुपचूप रिकामे नाहीpipefail — आतला कोणताही command fail झाला तर पूर्ण pipeline failtrap — शेवटी नेहमी चालणारी साफसफाई, Ctrl-C नंतर सुद्धाdry run — काय केले असते ते सांगा, प्रत्यक्ष न करता
1🚨 strict mode — तीन switches, तीन शांत अपयशेset -ecd /nowhere; rm -rf *→ नापास cd वर थांबते — पुढे जात नाहीset -urm -rf "$DRI/" (typo)→ न ठरवलेली variable = चूक, rm चालण्याआधीset -o pipefailbad | sort | head→ नापास pipe नापास — फक्त शेवटची cmd नाहीत्याशिवाय:2🧹 trap — काहीही झाले तरी आवराtmp=$(mktemp); mkdir lockकाम …exit 0चूक (set -e)Ctrl-C (INT)trap … EXITकाहीही झाले तरी चालतेrm -f tmp; rmdir lockEXIT · ERR · INT · TERM — backup.sh मधले lock trap सोडते, Ctrl-C वरही3🧪 तालीम — dry runs आणि shellcheckrun() { if [[ $DRY_RUN == 1 ]]; then log "would: $*"; else "$@"; fi; }$ DRY_RUN=1 bin/backup.shwould: tar czf … data/(कशालाही हात नाही)$ bin/backup.shbackup-2026-09-22.tgz okझाले (4 KB)rm -rf $DIR/SC2086: double quote लावा —globbing आणि word splitting टाळायलाrm -rf "${DIR:?}/"shellcheck script.sh — bash जाणणारा linter; CI मध्ये चालवाआधी temp फाइल मध्ये लिहा, मग mv (atomic) · अपयश चालत असेल तर || true · if / && / || च्या आत set -e बंद असते — अपयशाचे मार्ग तपासा (L12)
⏪ आधी

safety शिवाय fail झालेला cd किंवा variable मधील typo मुळे rm -rf पुढे चालत राहतो आणि गुपचूप चुकीच्या files delete करतो.

💡 काय

set -euo pipefail म्हणजे strict mode: error वर थांबा, unset variables ला error माना, आणि pipe चा कोणताही भाग fail झाला तर pipe fail.

⚙️ कसे

trap … EXIT काहीही झाले तरी rm -f tmp; rmdir lock सारखी साफसफाई चालवतो, error किंवा Ctrl-C वर सुद्धा.

🎯 का

मोठ्याने fail होणाऱ्या आणि साफसफाई करणाऱ्या scripts अर्धवट काम सोडत नाहीत; DRY_RUN आणि shellcheck चुका आधीच पकडतात.

🚀 पुढे

पुढे तुम्ही इमारतीतील इतर processes आणि trap ज्या signals ऐकतो त्यांना भेटाल.

🧪 Try it here — switches बदला, नापास होणारी ओळ निवडा, script कुठे थांबते आणि trap काय आवरते ते पहा

संपूर्ण धडा 08 वाचा →

9 👥 Processes & jobs

इमारतीत कोण आहे — ps, kill आणि signals, & आणि wait, jobs, nohup, xargs -P; PID 1 आणि zombies.

🧒 सोप्या शब्दांत

शाळेच्या इमारतीतील प्रत्येकाकडे एक badge असतो: एक क्रमांक आणि त्याला कोणी आणले त्याचे नाव. चालू programs पण तसेच: प्रत्येकाला PID क्रमांक आणि एक parent असतो. एखाद्याला घरी पाठवायला announcement speaker वापरतात: TERM म्हणजे 'कृपया निघा', आधी आवराआवर करू देतो, तर KILL लगेच बाहेर काढतो, साफसफाईला वेळ नाही. docker stop आधी नम्रपणे सांगतो, 10 seconds थांबतो, मग KILL वापरतो.

📖 नवे शब्दprocess — आत्ता चालू असलेला programPID — process चा badge क्रमांक; PPID म्हणजे त्याच्या parent चा क्रमांकsignal — process ला छोटा निरोप, उदा. TERM (कृपया थांबा) किंवा KILL (आत्ताच थांबा)PID 1 — इमारतीचा प्रमुख: पहिला process, ज्याच्यापासून बाकीचे येतात& and wait — job background मध्ये सुरू करा, मग तो संपेपर्यंत थांबा
1👥 इमारतीत कोण आहे — process चे झाडPID 1 init / systemd (root)sshd 812bash 4021 (तुम्ही)school.sh 4055grep 4056cron 900$ ps -o pid,ppid,cmd4055 4021 school.sh4056 4055 grep$ pgrep -f school4055प्रत्येक process: PID, पालक (PPID), user · PID 1 म्हणजे मुख्याध्यापक — init, किंवा तुमच्या container चा entrypoint2📣 signals — ध्वनिक्षेपकkill -TERM 4055कृपया थांबा — trap आवरू शकतेkill -INT (Ctrl-C)व्यत्यय, तीच सभ्यताkill -HUPconfig पुन्हा वाचाkill -KILL 4055आत्ता गायब — आवरणे शक्य नाहीdocker stop:TERM … संपवायला 10 sमग KILLTERM दुर्लक्षित केले तरी Docker मारतेच — TERM trap करा, संपवा, exit3⏳ background, wait, आणि एका वेळी चारक्रमाने: 4 jobs × 1 sjob 1job 2job 3job 4= 4 sxargs -P 4 · किंवा cmd & … waitjob 1job 2job 3job 4= 1 scmd & → मागे चालते; $! तिचा PID · wait तिची वाट पाहतेjobs · fg · bg · nohup cmd & तुमच्या logout नंतरही जगते🧟 zombie: संपली, कोणी वाट पाहिली नाही — PID 1 ने आवरायचे (tini)exec cmd shell च्या जागी येते म्हणून signals खऱ्या program पर्यंत पोहोचतातsmoke test ची L09: (sleep 1; echo) & wait — केअरटेकर घंटा वाजवतो आणि प्रतिध्वनीची वाट पाहतो · timeout 30 cmd
⏪ आधी

process tools शिवाय काय चालू आहे ते दिसत नाही, अडकलेला job नम्रपणे थांबवता येत नाही, किंवा काम parallel चालवता येत नाही.

💡 काय

प्रत्येक process ला PID, parent PPID आणि user असतो, आणि सगळे PID 1 (init किंवा container entrypoint) खालील एका tree मध्ये असतात.

⚙️ कसे

ps आणि pgrep school.sh ला 4055 म्हणून शोधतात; kill -TERM थांबायला सांगतो म्हणजे trap साफसफाई करू शकतो, kill -KILL लगेच संपवतो.

🎯 का

docker stop आधी TERM पाठवतो, 10 s थांबतो, मग KILL; म्हणून TERM trap करणारी script अचानक तुटण्याऐवजी नीट बंद होते.

🚀 पुढे

background jobs समजल्यावर पुढच्या lesson मध्ये cron ची घंटा त्यांना वेळापत्रकानुसार सुरू करते.

🧪 Try it here — चालू script ला signals पाठवा आणि काय होते ते पहा — मग एका वेळी चार चालवा

संपूर्ण धडा 09 वाचा →

10 🔔 वेळापत्रक & automation

घंटा — cron, systemd timers, lock फाइल्स, logs, idempotent runs; एकाच वेळी दोनदा कधीच न चालणारा रात्रीचा backup.

🧒 सोप्या शब्दांत

शाळेची घंटा कोणी न दाबता ठरलेल्या वेळी वाजते. computer साठी cron ही घंटा आहे: '0 2 * * *' ही ओळ म्हणजे 'रोज रात्री 02:00 ला backup चालवा'. दोन backups एकाच वेळी चालू नयेत म्हणून पहिला backup एक lock folder बनवतो; दुसऱ्याला तो आधीच दिसतो आणि तो थांबतो. आणि job दोनदा चालला तरी जादा नुकसान कधीच होऊ नये.

📖 नवे शब्दcron — ठरलेल्या वेळी commands चालवणारी अंगभूत घंटाcron line — वेळेचे पाच fields (minute hour day month weekday), मग commandlock — 'इथे कोणी काम करत आहे' ची पाटी, म्हणजे एका वेळी एकच runidempotent — पुन्हा चालवले तरी तोच निकाल, दुप्पट नुकसान नाही
1🔔 घंटा — cron ची ओळ, field-field0मिनिट2तास*दिवस*महिना*वार/srv/school/bin/backup.shcommand — absolute path!रोज रात्री 02:00ओळम्हणजे*/5 * * * *दर 5 मिनिटांनी0 9 * * 1-5कामाच्या दिवशी 09:0030 23 1 * *महिन्याच्या 1 ला 23:30crontab -e · cron ला PATH नाही आणि तुम्ही नाही: PATH ठरवा, REGISTER ठरवा, absolute paths वापरा2🔒 एका वेळी एक — lockrun A (02:00, अजून चालू)mkdir lock ✓tar … (3 मिनिटे)run B (उद्याची 02:00 लवकर येते)mkdir lock ✗die "दुसरा backup चालू आहे"mkdir atomic आहे: दोन runs दोन्ही ते बनवू शकत नाहीत · EXIT वर trap rmdir lockidempotent: दोनदा चालवा, तोच निकाल · प्रत्येक run ला वेळेसह एक ओळ log3🌙 backup.sh — tar → तपासा → rotate → logtar czf backup-2026-09-22.tgz data/tar -tzf … (उघडते का?)rotate: 7 ठेवा, सगळ्यात जुने काढाlog: 02:00:03 झाले (4 KB)🗄️-7d🗄️-6d🗄️-5d🗄️-4d🗄️-3d🗄️-2d🗄️-1d🗄️आजआठ archives, सगळ्यात जुने जातेsystemd: OnCalendar=daily · journalctl -u backup · k8s: CronJob · AWS: EventBridgeशांत यश अगदी कधीच न चालल्यासारखे दिसते — MAILTO किंवा तुम्ही खरोखर वाचता ते logकधीच restore न केलेला backup म्हणजे अफवा: दर महिन्याची restore तालीम हीच खरी परीक्षाDRY_RUN=1 bin/backup.sh काय करेल ते सांगते · --keep 7 · lock आणि trap चार ओळी
⏪ आधी

scheduling शिवाय कोणालातरी रोज रात्री हाताने backup चालवायचे लक्षात ठेवावे लागते, आणि दोन runs एकमेकांना धडकू शकतात.

💡 काय

cron ही घंटा आहे: पाच fields ची एक ओळ, minute hour day month weekday, आणि मग चालवायचा command.

⚙️ कसे

0 2 * * * /srv/school/bin/backup.sh रोज रात्री 02:00 ला चालतो, आणि mkdir lock एका वेळी एकच run चालेल याची खात्री करतो.

🎯 का

mkdir atomic असल्याने आणि runs idempotent असल्याने nightly backup एकाच वेळी दोनदा चालत नाही आणि पुन्हा चालवल्यास नुकसान करत नाही.

🚀 पुढे

cron ला PATH नसतो आणि तुम्हीही नसता; हे तुम्हाला CI आणि containers साठी तयार करते, जिथे तुमच्या scripts पुढे चालतात.

🧪 Try it here — cron ची ओळ लिहा, शब्दांत वाचा, पुढच्या तीन घंटा पहा — मग दोनदा वाजवा

संपूर्ण धडा 10 वाचा →

11 📮 CI & containers मधल्या scripts

मेलरूममधला केअरटेकर — shebangs, bash विरुद्ध POSIX sh, entrypoints, env आणि गुपिते, करार म्हणून exit codes.

🧒 सोप्या शब्दांत

पत्र पोस्ट करताना तुम्ही post office मध्ये उभे राहत नाही; ते पोहोचले की नाही हे नंतर कळते. CI तुमची script दूरच्या computer वर चालवते, जिथे screen नाही आणि प्रश्नांना उत्तर द्यायला कोणी नाही; ती फक्त exit code वाचते: 0 म्हणजे check हिरवा, बाकी काहीही म्हणजे लाल. container मध्ये settings आणि secrets environment values म्हणून येतात, आणि exec खऱ्या program ला जागा देतो म्हणून थांबण्याचे signals त्याच्यापर्यंत पोहोचतात.

📖 नवे शब्दCI — प्रत्येक push वर तुमचे tests चालवून हिरवा किंवा लाल दाखवणारा robotcontainer — program आणि त्याला लागणारे सगळे घेऊन जाणारा बंद डबाentrypoint — container सुरू झाल्यावर चालणारी पहिली scriptenv variable — बाहेरून दिलेली setting, उदा. PORT=3000exec — script च्या जागी खरा program आणा, म्हणजे तो PID 1 होतो
1📮 मेलरूम — CI तुमची script चालवते आणि फक्त exit code वाचतेgit pushGitHububuntu runnerrun: bash tests/run_tests.sh14 checks, 0 failedexit 0✓ exit 0 → हिरवा✗ exit 1 → लालterminal नाही, प्रश्न नाहीत, रंग नाहीत:exit code हाच निकालCI/CD शाळा या चाचण्या प्रत्येक push वर चालवते"माझ्या machine वर चालते": cron आणि CI ला वेगळे PATH, HOME आणि locale — ज्या container मध्ये चालणार तिथेच तपासा2🐳 entrypoint — container च्या आत#!/usr/bin/env bashset -euo pipefail: "${PORT:=3000}" # env, default सहexec "$@" # PID 1 होतेexec shell च्या जागी येते: signals खऱ्या program पर्यंतalpine ला sh आहे, bash नाही → #!/bin/sh आणि फक्त POSIX[[ ]], arrays, ${var//x/y} bash च्या — shebang ठरवते3🔐 गुपिते आणि environment — script मध्ये कधीच नाही, git मध्ये कधीच नाहीAPI_KEY=sk-…script मध्ये ✗secret.envgit मध्ये ✗गुपितांचे भांडारAPI_KEY=… (env)"$API_KEY"चालताना वाचले, कधीच लिहून ठेवले नाहीगुपिताभोवती set +x — trace ते छापेल · CI ची गुपितेही environment variables म्हणून येतातफक्त bashPOSIX sh[[ ]] arrays ${var//x/y} local[ ] arrays नाहीत बदलांसाठी sed
⏪ आधी

स्पष्ट contract शिवाय तुमच्या machine वर चालणारी script वेगळ्या PATH आणि HOME असलेल्या CI किंवा container मध्ये fail होते.

💡 काय

CI आणि containers मध्ये terminal नाही, prompts नाहीत, आणि exit code हाच एकमेव निकाल कोणी वाचतो.

⚙️ कसे

runner bash tests/run_tests.sh चालवतो: exit 0 हिरवा, exit 1 लाल; entrypoint ${PORT:=3000} ठरवून मग exec "$@" करतो.

🎯 का

exec मुळे खरा program PID 1 होतो म्हणून signals त्याच्यापर्यंत पोहोचतात, आणि settings व secrets prompts ऐवजी env मधून येतात.

🚀 पुढे

CI/CD school हे tests प्रत्येक push वर चालवते, आणि पुढचा lesson scripts ना debug आणि test कसे करायचे ते दाखवतो.

🧪 Try it here — base image, shebang आणि exit code निवडा — मेलरूम काय म्हणते ते वाचा

संपूर्ण धडा 11 वाचा →

12 🔬 Debugging & testing

bash -x, PS4, shellcheck, ~30 ओळींच्या bash मधला test runner — आणि कळस-प्रकल्प: backup, तपासलेला.

🧒 सोप्या शब्दांत

विज्ञानाचा प्रयोग चुकला की तुम्ही तो हळू हळू पुन्हा करता आणि प्रत्येक पायरी लिहून ठेवता. bash -x script साठी हेच करतो: प्रत्येक command जसा चालला तसाच, ओळ क्रमांकासह, छापतो, म्हणून अंदाज न लावता कुठे बिघडले ते दिसते. मग एक छोटा test runner 14 प्रश्नांच्या checklist सारखा काम करतो, प्रत्येकावर pass किंवा fail लावतो, म्हणजे एक भाग दुरुस्त करताना दुसरा गुपचूप तुटत नाही.

📖 नवे शब्दbash -x — script चालवताना ती चालवत असलेला प्रत्येक command छापाPS4 — trace केलेल्या प्रत्येक ओळीपुढे छापले जाणारे लेबल, उदा. ओळ क्रमांकshellcheck — तुमची script वाचून सामान्य चुकांबद्दल इशारा देणारा checkertest runner — प्रत्येक check चालवून pass किंवा fail सांगणारी script
1🔬 bash -x — प्रत्येक command, विस्तारित$ PS4='+ ${LINENO}: ' bash -x bin/school.sh list --class 3A+ 12: set -euo pipefail+ 13: HERE=/home/you/school/bin+ 22: grep ,3A, /home/you/school/data/register.csv+ 22: sort+ 22: column -t -s,shell ने खरोखर चालवली तशी प्रत्येक command, ओळ क्रमांकांसहएका भागाभोवती set -x / set +x · अंदाज बांधण्याआधीचे पहिले साधन2🧪 test runner — ~30 ओळींच्या bash मध्ये 14 checkscheck "name" "wanted" "$(cmd)" # output मध्ये मजकूर आहे? ✓ : ✗list बीज दाखवते✓list --class गाळते✓enrol ओळ जोडते✓दोनदा enrol idempotent✗ हवे होते "already", मिळाले "enrolled"enrol चुकीचा वर्ग नाकारते (exit 1)✓14 checks, 1 failed → exit 13🧹 shellcheck + 🏆 कळस-प्रकल्पप्रत्येक run ला temp नोंदवही · कोणतीही check नापास तर exit 1 · bats म्हणजे त्याच आकाराची framework आवृत्तीअपयशाचे मार्ग तपासा: नसलेली नोंदवही, चुकीचा वर्ग, lock केलेली directory — set -e ते तुमच्यासाठी करणार नाही🏆 कळस-प्रकल्प: backup.sh, तपासलेलाdry run कशालाही हात लावत नाही ✓खरा run: tar -tzf तपासते ✓rotation --keep पाळते ✓lock दुसरा run नाकारते ✓अपयशाचे मार्ग तपासलेले ✓CI मध्ये shellcheck: quotes नसलेल्या vars, निरुपयोगी cats, [ विरुद्ध [[, -r नसणे, मृत code — प्रत्येक warning एकदा दुरुस्त करा
⏪ आधी

debugging tools शिवाय script का fail झाली याचा अंदाज लावत बसता, आणि tests शिवाय एखादा fix गुपचूप enrol किंवा backup तोडू शकतो.

💡 काय

bash -x प्रत्येक command shell ने खरोखर जसा चालवला तसा छापतो, आणि एक छोटा test runner प्रत्येक वर्तन तपासतो.

⚙️ कसे

PS4='+ ${LINENO}: ' bash -x ओळ क्रमांक जोडतो, आणि check "name" "wanted" "$(cmd)" ~30 ओळींच्या bash मध्ये 14 checks चालवतो.

🎯 का

"enrol twice is idempotent" सारखा fail होणारा check nightly backup पर्यंत पोहोचण्याआधीच नेमका bug दाखवतो.

🚀 पुढे

हा tested backup हा capstone आहे, आणि खऱ्या teams मध्ये CI प्रत्येक push वर हाच runner चालवते.

🧪 Try it here — bug घाला, 14 checks चालवा, runner वाचा — आणि एक command bash -x ने trace करा

संपूर्ण धडा 12 वाचा →

धडा 01 सुरू करा → 🗓️ अभ्यास योजना (4 आठवडे) 📐 सर्व 12 धड्यांच्या आकृत्या 🧪 प्रश्नमंजुषा (15 प्रश्न) ⏮️ आधी काय होते & फायदे-तोटे