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

ЁЯзй рдзрдбрд╛ 07 тАФ Functions рдЖрдгрд┐ arguments: рджрд┐рдирдЪрд░реНрдпрд╛

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


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

рдзрдбреЗ 01тАУ07. рдПрдХрд╛ рджрд┐рдирдЪрд░реНрдпреЗрд▓рд╛ рдирд╛рд╡ рджреЗрдгреЗ, рддрд┐рд▓рд╛ arguments рджреЗрдгреЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЦрд▒реНрдпрд╛ script рдордзреНрдпреЗ рдЕрд╕рдгрд╛рд░рд╛ рд╕рд╛рдВрдЧрд╛рдбрд╛.

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

рд░реЛрдЬ рд╕рдХрд╛рд│реА рдХреЗрдЕрд░рдЯреЗрдХрд░рд▓рд╛ рддреНрдпрд╛рдЪ рд╕рд╛рдд рдУрд│реА рд╕рд╛рдВрдЧрдгреНрдпрд╛рдРрд╡рдЬреА, рддреБрдореНрд╣реА рддреНрдпрд╛ рдПрдХрд╛ рдирд╛рд╡ рджрд┐рд▓реЗрд▓реНрдпрд╛ рдХрд╛рд░реНрдбрд╡рд░ рд▓рд┐рд╣рд┐рддрд╛ тАФ рдПрдХ function тАФ рдЖрдгрд┐ рддреНрдпрд╛рд▓рд╛ рд▓рд╛рдЧрдгрд╛рд░реА рдорд╛рд╣рд┐рддреА рджреЗрддрд╛: cmd_enrol Zoya 3B A. рдЖрдд, $1 рдореНрд╣рдгрдЬреЗ рдкрд╣рд┐рд▓реА рдорд╛рд╣рд┐рддреА, $2 рджреБрд╕рд░реА, "$@" рд╕рдЧрд│реА. script рдЪреА рд╢реЗрд╡рдЯрдЪреА рдУрд│, main "$@", рддреБрдореНрд╣реА рдЯрд╛рдЗрдк рдХреЗрд▓реЗрд▓реЗ рд╕рдЧрд│реЗ рдПрдХрд╛ рджрд┐рдирдЪрд░реНрдпреЗрдХрдбреЗ рджреЗрддреЗ, рдЬреА рдХреЛрдгрддреЗ рдХрд╛рд░реНрдб рд╡рд╛рдкрд░рд╛рдпрдЪреЗ рддреЗ рдард░рд╡рддреЗ.

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

flowchart TD
  M["main \"$@\""] --> C{"case $cmd"}
  C -->|list| L["cmd_list --class 3A"]
  C -->|enrol| E["cmd_enrol NAME CLASS [GRADE]"]
  C -->|report| R["cmd_report"]
  C -->|"*"| U["die 'unknown command'"]

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

ЁЯдФ рдХрд╛

functions рдореБрд│реЗрдЪ 70 рдУрд│реАрдВрдЪреА script 700 рдУрд│реАрдВрд╡рд░рд╣реА рд╡рд╛рдЪрддрд╛ рдпреЗрддреЗ, рджреЛрди scripts рдПрдХ logger рд╡рд╛рдЯреВрди рдШреЗрддрд╛рдд, рдЖрдгрд┐ рддреБрдореНрд╣реА рдПрдЦрд╛рджрд╛ рддреБрдХрдбрд╛ рд╡реЗрдЧрд│рд╛ рдХрд╛рдвреВрди test рдХрд░реВ рд╢рдХрддрд╛ (рдзрдбрд╛ 12).

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

cmd_enrol local рдЖрдгрд┐ ${1:?} рд╡рд╛рдкрд░рддреЛ; cmd_list --class рдЦрд╛рддреЛ; main shift || true рдиреЗ sub-command рд╕реЛрд▓реВрди рдХрд╛рдврддреЛ рдЖрдгрд┐ case рдиреЗ рдХрд╛рдо рд╡рд╛рдЯрддреЛ; usage --help рд╕рд╛рдареА 0 рдиреЗ рдЖрдгрд┐ рдЪреБрдХреАрдЪреНрдпрд╛ рд╡рд╛рдкрд░рд╛рд╕рд╛рдареА 1 рдиреЗ exit рд╣реЛрддреЗ.

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

bin/school.sh --help
bin/school.sh list --class 3B --bogus; echo "exit $?"          # the flag loop refuses
source lib/log.sh; log "hello from my shell"; need tar && echo "tar is here"
f() { local x="$1"; echo "got $#: $*"; return 3; }; f a "b c"; echo "exit $?"
# add a sub-command: copy cmd_report, name it cmd_count, print $(tail -n +2 "$REGISTER" | wc -l), wire it into main's case

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

header comment рдордзрд▓рд╛ help text; unknown flag --bogus рдЖрдгрд┐ exit 1; timestamp рдЕрд╕рд▓реЗрд▓рд╛ hello; got 2: a b c рдЖрдгрд┐ рдордЧ exit 3. рддреБрдордЪрд╛ count sub-command рдЬреЛрдбрд▓реНрдпрд╛рд╡рд░ 5 рдЫрд╛рдкрддреЛ.

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

рддреБрдореНрд╣реА рдЦрд▒реНрдпрд╛ CLI рдЪрд╛ рд╕рд╛рдВрдЧрд╛рдбрд╛ рд╡рд╛рдЪреВ рдЖрдгрд┐ рд╡рд╛рдврд╡реВ рд╢рдХрддрд╛: functions, arguments, flags, dispatch, help.

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдПрдХрд╛ screen рдкреЗрдХреНрд╖рд╛ рдореЛрдареЗ рдЭрд╛рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ ops tool рдЪрд╛ рд╣рд╛рдЪ рд╕рд╛рдВрдЧрд╛рдбрд╛ рдЕрд╕рддреЛ; рдЬреНрдпрд╛рдВрдЪрд╛ рдирд╕рддреЛ рддреНрдпрд╛ 400 рдУрд│реАрдВрдЪреНрдпрд╛ files рдирд╛ рд╣рд╛рдд рд▓рд╛рд╡рд╛рдпрдЪреА рдХреЛрдгрд╛рдЪреАрдЪ рд╣рд┐рдВрдордд рд╣реЛрдд рдирд╛рд╣реА.

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

рдзрдбрд╛ 08 тАФ errors рдЖрдгрд┐ safety: рдЖрдЧреАрдЪреА рддрд╛рд▓реАрдо тАФ рдореЛрдареНрдпрд╛рдиреЗ fail рд╡реНрд╣рд╛, рд╕рд╛рдлрд╕рдлрд╛рдИ рдХрд░рд╛, рдХрд╛рд╣реАрд╣реА рди рдмрджрд▓рддрд╛ рд╕рд░рд╛рд╡ рдХрд░рд╛.

ЁЯзй Lesson 07 тАФ Functions & arguments: routines

ЁЯУН You are here: Lesson 07 of 12 ┬╖ Next: lesson-08-errors-safety


ЁЯУж What's in this branch

Lessons 01тАУ07. Naming a routine, handing it arguments, and the skeleton every real script shares.

ЁЯзТ Explain like I'm 5

Instead of telling the caretaker the same seven lines every morning, you write them on a card with a name тАФ a function тАФ and hand it any details it needs: cmd_enrol Zoya 3B A. Inside, $1 is the first detail, $2 the second, "$@" all of them. The script's last line, main "$@", hands everything you typed to one routine that decides which card to use.

ЁЯЧ║я╕П Diagram

flowchart TD
  M["main \"$@\""] --> C{"case $cmd"}
  C -->|list| L["cmd_list --class 3A"]
  C -->|enrol| E["cmd_enrol NAME CLASS [GRADE]"]
  C -->|report| R["cmd_report"]
  C -->|"*"| U["die 'unknown command'"]

тЭУ What

ЁЯдФ Why

Functions are how a 70-line script stays readable at 700, how two scripts share a logger, and how you test a piece in isolation (lesson 12).

ЁЯФз How (in this repo)

cmd_enrol uses local and ${1:?}; cmd_list eats --class; main peels the sub-command with shift || true and dispatches with case; usage exits 0 for --help and 1 for misuse.

ЁЯзк Try it

bin/school.sh --help
bin/school.sh list --class 3B --bogus; echo "exit $?"          # the flag loop refuses
source lib/log.sh; log "hello from my shell"; need tar && echo "tar is here"
f() { local x="$1"; echo "got $#: $*"; return 3; }; f a "b c"; echo "exit $?"
# add a sub-command: copy cmd_report, name it cmd_count, print $(tail -n +2 "$REGISTER" | wc -l), wire it into main's case

тЬЕ Verify тАФ what you should see

The help text from the header comment; unknown flag --bogus and exit 1; a timestamped hello; got 2: a b c then exit 3. Your count sub-command prints 5 once wired in.

ЁЯПБ What you just proved

You can read and extend a real CLI's skeleton: functions, arguments, flags, dispatch, help.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: every ops tool that grew past a screen has this skeleton; the ones that did not are the 400-line files nobody dares to edit.

тПня╕П Next

Lesson 08 тАФ errors & safety: the fire drill тАФ fail loudly, clean up, rehearse without touching anything.

тЖР Previousconditions loopsNext тЖТerrors safety

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