Step 1 of 5 · Reading · ~3 min
Learn
Getting Started
Variables
By the end of this lesson you can store text in a variable, read it back safely, join variables into longer strings, and read lines of input into variables. Bash variables hold text and nothing else: no integers, no objects. (Arithmetic is a special context you will meet next lesson.)
Rule 1: no spaces around =
city="Oslo" # correct
city = "Oslo" # wrong
You know from last lesson that bash cuts a line into words and treats the first word as a command. The second line is the command city with two arguments, = and Oslo, and bash replies city: command not found. Assignment is name=value with nothing between the parts.
Rule 2: $ to read, nothing to write
greeting="Hello"
echo "$greeting" # Hello
greeting="$greeting!" # write without $, read with $
echo "$greeting" # Hello!
Bash substitutes the variable's text into the line before the command runs, so the line you wrote is a template and the line that runs is the expanded result.
A variable name is as long as the letters, digits and underscores that follow the $. When your text continues with more of those characters, mark the end with braces:
pet="cat"
echo "$pets" # prints an empty line: bash looked up a variable called pets
echo "${pet}s" # cats
Quote every expansion
An unquoted expansion is split into words on whitespace, and each word that contains * or ? is then matched against file names.
song="Let it be"
echo $song # Let it be (three spaces became one)
echo "$song" # Let it be (kept)
The same mechanism destroys data: with file="my notes.txt", rm $file runs rm my notes.txt and deletes two files you did not mean. rm "$file" passes one argument. The discipline is mechanical: write "$var" every time, unless you can say why you want splitting.
Double quotes allow expansion. Single quotes suppress it: '$song' is a dollar sign followed by four letters.
Reading input into variables
read -r first rest
read takes one line from stdin and assigns it to the names you give. With several names, the first words go to the first names and the remainder goes to the last one. Leading and trailing whitespace is trimmed, inner spacing is kept, and -r stops backslashes from being treated as escapes (always write it). With the line Ada Lovelace of London , first is Ada and rest is Lovelace of London.
When the input has one value per line, use one read per value. A single read a b against two lines leaves b empty, which is the classic wrong answer.
Environment variables, briefly
Your script inherits variables such as $HOME and $PATH from whatever launched it. By convention ALL_CAPS names are for inherited or exported configuration and lowercase names are for your script's own use. export level=3 hands a variable down to programs your script starts.
Common mistakes
- Spaces around
=.count = 5runs a command namedcount. - A
$on the left.$count=5expands$countfirst and then tries to run the result as a command. - Missing braces.
"$pet_old"reads a variable namedpet_old, notpetfollowed by_old, and silently prints nothing. - Unquoted expansion. It collapses runs of spaces and can match file names, so output is wrong only on some inputs.
Your exercise
Build a release name from two values you read, using a variable to hold the shared part and printing it in two forms. The most likely mistake is a name that bash reads as a longer variable than you meant.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…