Before this lesson, complete bash-loops-arrays.
This course runs GNU Bash with ordinary GNU text tools in a fresh Linux sandbox.
A Bash function runs in the current shell unless you explicitly put it in a subshell. That makes it useful for changing caller state intentionally, but an accidental global assignment can also leak into later commands. Declare working variables with local and pass values as arguments. Bash locals use dynamic scope: a helper called by the function can see those locals. Avoid relying on this implicitly when an argument would express the dependency clearly.
Apply the contract
A function has its own positional parameters. Calling render "$@" forwards each original argument intact; shift then removes one function argument without shifting the script's argument list outside that call. Save the label before shifting and guard the shift when there may be no arguments. $# counts the current function arguments.
prefix=outer
render() { local prefix=$1; shift; printf '%s:%s\n' "$prefix" "$@"; }
render inner hello
printf '%s\n' "$prefix"Reason about the edge cases
Parameter defaults distinguish absence from emptiness. ${1-label} uses label only when the first parameter is unset. ${1:-label} also substitutes for a supplied empty string. The lab allows an empty label, so that distinction is observable. A function's return status comes from its final command unless return selects another status. Do not confuse that status with a string result written to stdout. Here the renderer writes formatted lines and the caller then prints its unchanged prefix; both the produced text and the surviving caller state matter.
Practice
The script starts with a caller variable prefix=outer. A render function treats its first argument as a label (default label only when absent), prints LABEL:VALUE for each remaining argument, and preserves all values. After calling it with the script arguments, print scope:outer. The caller prefix must survive. A supplied empty label is valid.
Run sample starts again from the first public fixture and grants no mastery evidence. Submit checks all fixtures, including edge cases. Read the specification before editing; the bug and fill phases share the build’s contract. Flashcards reinforce recall on a separate schedule.