Reading — step 1 of 5
Learn
Variables
Bash variables hold text. Not integers, not objects — strings, always (arithmetic is a special context you'll meet next lesson). The syntax has two rules that break everyone arriving from real languages, so let's break them on purpose, now, where it's cheap.
Rule 1: no spaces around =
name="Ada" # correct
name = "Ada" # WRONG — bash runs the command `name` with args `=` and `"Ada"`
Remember words-and-commands from last lesson? name = "Ada" parses as command name — bash helpfully reports name: command not found, a bizarre error until you know why it happens, obvious forever after. Assignment is name=value, welded together.
Rule 2: $ to read, nothing to write
greeting="Hello"
echo "$greeting" # read with $
greeting="$greeting!" # write without $, read with $ — both in one line
$name (or ${name} when you need boundaries: "${file}_backup" — without braces bash would look for a variable named file_backup) substitutes the variable's text into the line before the command runs. That "before" is the key to bash's whole execution model: the line you wrote is not the line that runs; it's a template that gets expanded.
The rule that separates pros from postmortems: quote your variables
file="my report.txt"
rm $file # runs: rm my report.txt → deletes "my" and "report.txt" (!!)
rm "$file" # runs: rm with ONE argument → deletes the right file
Unquoted $file gets substituted, then split into words on whitespace. A filename with a space becomes two arguments; a variable containing * gets glob-expanded into every file in the directory. This is not a rare edge case — it's the single most common bash bug in existence, and it has destroyed real data (search "steam bash bug" someday). The discipline is mechanical: always write "$var", never bare $var, unless you can articulate why you want word-splitting. Double quotes allow substitution ("Hello, $name"); single quotes suppress it ('$name' is literally a dollar sign and four letters).
Reading input
read a # read one LINE from stdin into a
read b # read the next line
echo "$((a + b))"
read grabs a line and assigns it. Grader input often puts one value per line — two reads, as above. Multiple values on one line split across names: read x y assigns first word to x, rest to y. Check the exercise's input format examples and pick accordingly; a read a b against line-separated input leaves b empty, which is this exercise's classic wrong answer.
Environment variables, briefly
Your script inherits variables from the shell that launched it — $HOME, $PATH, $USER — and by convention ALL_CAPS names are for those and exported config; lowercase names are for your script's own locals. export mine=1 pushes a variable down into programs your script launches. That's the whole environment model in three sentences, and it's why config-by-env-var (the pattern every deployment system uses) works.
Your exercise: Sum Two Numbers
Two reads and an arithmetic expansion (formally introduced next lesson):
read a
read b
echo "$((a + b))"
Quoting habit check: the $((…)) result has no spaces, but wrapping it in quotes anyway costs nothing and keeps the reflex strong. Three lines, two rules, one habit — that's bash variables.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…