Course outline · 0% complete

0/29 lessons0%

Course overview →

Functions and real automation

lesson 9-3 · ~11 min · 26/29

Functions: name a block of commands

A function is a reusable mini-script inside your script:

greet() {
  echo "Hello, $1!"
}
greet Ada

Define once with name() { ... }, call by name like any command. Inside the function, $1, $2, $# refer to the function's arguments, exactly like a script's arguments in lesson 8-2. This is how a growing script stays readable: small named pieces.

One function, two calls

The function is defined once and then called twice with a different argument each time.

greet() {
  echo "Hello, $1!"
}
greet Ada
greet Grace

Output

Hello, Ada!
Hello, Grace!

Nothing is printed by the definition itself. The body sits dormant until the name is invoked, and each invocation supplies its own $1, which is why the same three lines of code produce two different greetings.

Automation #1: batch rename

Everything converges. Renaming 300 files by hand is an afternoon, or it's three lines:

for f in *.txt; do
  mv "$f" "${f%.txt}.md"
done

One new tool: ${f%.txt} is the variable's value with .txt chopped off the end (the % means "remove this suffix"). So notes.txt → notes → notes.md. The quotes around "$f" keep filenames with spaces in one piece, a habit worth building now.

The batch renamer in action

Three .txt files become .md files in a single loop, with lesson 3-2's mv doing the actual renaming.

touch notes.txt ideas.txt todo.txt
for f in *.txt; do
  mv "$f" "${f%.txt}.md"
done
ls

Output

ideas.md
notes.md
todo.md

The new name is built in two steps inside one expression. ${f%.txt} strips the old extension, leaving notes, and .md is then glued onto the result to give notes.md. No .txt file survives, because each one was renamed rather than copied.

Automation #2: a log summarizer

A function + grep -c (lesson 4-1) = an instant report tool for any log file. Notice $(command) below: command substitution captures a command's output into the middle of a string, the same trick you used with $(pwd) in lesson 2-1.

The summarize function

This script builds a five-line log and defines a summarize function that reports the error and warning counts for whatever file it is given in $1.

echo "INFO boot ok" > app.log
echo "ERROR disk full" >> app.log
echo "INFO user login" >> app.log
echo "ERROR no network" >> app.log
echo "WARN low memory" >> app.log
summarize() {
  echo "errors: $(grep -c ERROR "$1")"
  echo "warnings: $(grep -c WARN "$1")"
}
summarize app.log

Output

errors: 2
warnings: 1

How the counts get into the text

  • grep -c ERROR "$1" prints only the number of matching lines, thanks to the counting flag from lesson 4-1.
  • Wrapping that in $( ) is command substitution, which drops the number into the middle of the echo string instead of on a line of its own.
  • The filename arrives as $1, so the same function summarizes any log passed to it rather than being hardwired to app.log.

Inside a function called as deploy staging fast, $2 is fast.

Function calls get their own $1, $2, and $#, working just as they do for scripts in lesson 8-2. Here $1 is staging and $2 is fast. Whatever arguments the surrounding script received are shadowed for the duration of the call, so a function always sees the arguments it was given rather than the script's.