ЁЯПл The SchoolтА║ЁЯз╣ Shell scriptingтА║ЁЯФБ рдзрдбрд╛ 06 тАФ Conditions рдЖрдгрд┐ loops: рдХреЗрдЕрд░рдЯреЗрдХрд░рдЪреЗ рдирд┐рд░реНрдгрдп
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯФБ рдзрдбрд╛ 06 тАФ Conditions рдЖрдгрд┐ loops: рдХреЗрдЕрд░рдЯреЗрдХрд░рдЪреЗ рдирд┐рд░реНрдгрдп

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 06 ┬╖ рдкреБрдвреЗ: lesson-07-functions-arguments


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ06. рдлрд╛рдЯреЗ рдШреЗрдгреЗ рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ рдкреБрдиреНрд╣рд╛ рдХрд░рдгреЗ тАФ рдЖрдгрд┐ shell рдЪреЗ logic рдЗрддрд░ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рд╖реЗрдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реЗ рдХрд░рдгрд╛рд░реА рдЧреЛрд╖реНрдЯ.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдХреЗрдЕрд░рдЯреЗрдХрд░рдХрдбреЗ "true" рдЖрдгрд┐ "false" рдирд╕рддрд╛рдд. рддреНрдпрд╛рдЪреНрдпрд╛рдХрдбреЗ exit codes рдЕрд╕рддрд╛рдд: 0 рдиреЗ рд╕рдВрдкрдгрд╛рд░рд╛ command рдореНрд╣рдгрдЬреЗрдЪ "рд╣реЛрдп". рдореНрд╣рдгреВрди if grep -q "^Zoya," register.csv рдореНрд╣рдгрдЬреЗ "grep рд▓рд╛ рддреА рд╕рд╛рдкрдбрд▓реА рддрд░". [[ тАж ]] рд╣рд╛ рдПрдХ command рдЖрд╣реЗ рдЬреНрдпрд╛рдЪреЗ рдПрдХрдЪ рдХрд╛рдо рдореНрд╣рдгрдЬреЗ рдХрд╛рд╣реАрддрд░реА рддрдкрд╛рд╕рдгреЗ рдЖрдгрд┐ 0 рдХрд┐рдВрд╡рд╛ 1 рдиреЗ exit рд╣реЛрдгреЗ. Loops рд╕реБрджреНрдзрд╛ рддрд╕реЗрдЪ: command рд╣реЛрдп рдореНрд╣рдгрдд рд░рд╛рд╣рддреЛ рддреЛрдкрд░реНрдпрдВрдд while рдЪрд╛рд▓реВ рд░рд╛рд╣рддреЛ; for рдПрдХрд╛ рдпрд╛рджреАрддреВрди рдлрд┐рд░рддреЛ. cmd && next рдлрдХреНрдд рд╣реЛрдп рд╡рд░ next рдЪрд╛рд▓рд╡рддреЛ; cmd || other рдлрдХреНрдд рдирд╛рд╣реА рд╡рд░.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart TD
  C["grep -q '^Zoya,' register"] -->|exit 0| Y["then: already enrolled"]
  C -->|exit 1| N["else: append the row"]

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдкреНрд░рддреНрдпреЗрдХ deploy script рдореНрд╣рдгрдЬреЗ "health check pass рдЭрд╛рд▓рд╛ рддрд░ рдкреБрдвреЗ рдЪрд▓рд╛; рдирд╛рд╣реАрддрд░ roll back рдХрд░рд╛". рдкреНрд░рддреНрдпреЗрдХ batch job рдореНрд╣рдгрдЬреЗ "рдкреНрд░рддреНрдпреЗрдХ file рд╕рд╛рдареА". exit-code рдЪреЗ model рдиреАрдЯ рд╕рдордЬрд▓реЗ рдХреА set -e (рдзрдбрд╛ 08) рддреБрдордЪреНрдпрд╛ рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ рд╡рд╛рдЧрддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

valid_class() { [[ " $CLASSES " == *" $1 "* ]]; } тАФ рдПрдХ function рдЬреНрдпрд╛рдЪрд╛ рдирд┐рдХрд╛рд▓ рдореНрд╣рдгрдЬреЗ test рдЪрд╛ exit code. main case рдиреЗ рдХрд╛рдо рд╡рд╛рдЯрддреЛ. cmd_list while [[ $# -gt 0 ]] тАж shift 2 рдиреЗ flags рдЦрд╛рддреЛ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

if bin/school.sh list 2>/dev/null | grep -q Aishwarya; then echo "enrolled"; else echo "not enrolled"; fi
for c in 3A 3B 9Z; do bin/school.sh list --class "$c" >/dev/null 2>&1 && echo "$c: ok" || echo "$c: nothing"; done
while read -r line; do echo "row: $line"; done < <(tail -n +2 data/register.csv)
[[ "grade.csv" == *.csv ]] && echo "a csv"
n=0; for f in bin/*.sh; do n=$((n+1)); done; echo "$n scripts"

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

enrolled; 3A: ok, 3B: ok, 9Z: ok (рд░рд┐рдХрд╛рдорд╛ рд╡рд░реНрдЧ рд╕реБрджреНрдзрд╛ header рджрд╛рдЦрд╡рддреЛ тАФ exit 0 тАФ рд╣реА design рдЪреА рдирд┐рд╡рдб рд▓рдХреНрд╖рд╛рдд рдШреЗрдгреНрдпрд╛рд╕рд╛рд░рдЦреА рдЖрд╣реЗ); рдкрд╛рдЪ row: рдУрд│реА; a csv; 3 scripts.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рддреБрдореНрд╣реА рдХреЛрдгрддреНрдпрд╛рд╣реА command рдЪреНрдпрд╛ рдпрд╢рд╛рд╡рд░ рдлрд╛рдЯреЗ рдШреЗрдК рд╢рдХрддрд╛ рдЖрдгрд┐ loop рдХрд░реВ рд╢рдХрддрд╛, рдЖрдгрд┐ рдЦрд▒реНрдпрд╛ CLI рдЪрд╛ case/while рд╕рд╛рдВрдЧрд╛рдбрд╛ рд╡рд╛рдЪреВ рд╢рдХрддрд╛.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: until curl -sf /health; do sleep 2; done рд╣рд╛ рд╣рдЬрд╛рд░реЛ deploy scripts рдордзрд▓рд╛ readiness wait рдЖрд╣реЗ тАФ exit code рд╡рд░рдЪрд╛ рдПрдХ loop, рдмрд╛рдХреА рдХрд╛рд╣реА рдирд╛рд╣реА.

тПня╕П рдкреБрдвреЗ

рдзрдбрд╛ 07 тАФ functions рдЖрдгрд┐ arguments: рдирд╛рд╡ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рджрд┐рдирдЪрд░реНрдпрд╛, рдЖрдгрд┐ рдЦрд▒реНрдпрд╛ script рдЪрд╛ рд╕рд╛рдВрдЧрд╛рдбрд╛.

ЁЯФБ Lesson 06 тАФ Conditions & loops: the caretaker's decisions

ЁЯУН You are here: Lesson 06 of 12 ┬╖ Next: lesson-07-functions-arguments


ЁЯУж What's in this branch

Lessons 01тАУ06. Branching and repeating тАФ and the fact that makes shell logic different from every other language.

ЁЯзТ Explain like I'm 5

The caretaker has no "true" and "false". They have exit codes: a command that ends with 0 is "yes". So if grep -q "^Zoya," register.csv means "if grep finds her". [[ тАж ]] is a command whose only job is to test something and exit 0 or 1. Loops are the same: while keeps going while a command says yes; for walks a list. cmd && next runs next only on yes; cmd || other only on no.

ЁЯЧ║я╕П Diagram

flowchart TD
  C["grep -q '^Zoya,' register"] -->|exit 0| Y["then: already enrolled"]
  C -->|exit 1| N["else: append the row"]

тЭУ What

ЁЯдФ Why

Every deploy script is "if the health check passes, continue; else roll back". Every batch job is "for each file". Getting the exit-code model right is what makes set -e (lesson 08) behave as you expect.

ЁЯФз How (in this repo)

valid_class() { [[ " $CLASSES " == *" $1 "* ]]; } тАФ a function whose result is the test's exit code. main dispatches with case. cmd_list eats flags with while [[ $# -gt 0 ]] тАж shift 2.

ЁЯзк Try it

if bin/school.sh list 2>/dev/null | grep -q Aishwarya; then echo "enrolled"; else echo "not enrolled"; fi
for c in 3A 3B 9Z; do bin/school.sh list --class "$c" >/dev/null 2>&1 && echo "$c: ok" || echo "$c: nothing"; done
while read -r line; do echo "row: $line"; done < <(tail -n +2 data/register.csv)
[[ "grade.csv" == *.csv ]] && echo "a csv"
n=0; for f in bin/*.sh; do n=$((n+1)); done; echo "$n scripts"

тЬЕ Verify тАФ what you should see

enrolled; 3A: ok, 3B: ok, 9Z: ok (an empty class still lists a header тАФ exit 0 тАФ which is a design choice worth noticing); five row: lines; a csv; 3 scripts.

ЁЯПБ What you just proved

You can branch and loop on any command's success, and you can read the case/while skeleton of a real CLI.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: until curl -sf /health; do sleep 2; done is the readiness wait in a thousand deploy scripts тАФ a loop on an exit code, nothing more.

тПня╕П Next

Lesson 07 тАФ functions & arguments: routines with names, and the skeleton of a real script.

тЖР Previousvariables quotingNext тЖТfunctions arguments

This page is the lesson's README from the lesson-06-conditions-loops branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.