Everyone Can Learn Program
中文 Start learning
Core · LinuxLesson 6 of 6Free to read

Shell scripts · Linux and the Command Line

How do you turn commands you repeat into a script?

Course contents

Why you need it

If you type the same five commands every morning, a script types them for you, the same way every time. Deploy scripts, backups and health checks on real servers are mostly small shell scripts built from what you already know, plus variables, conditions and loops.

The intuition

  • Variable: name=ada (no spaces around =), used as $name.
  • Command result: n=$(grep -c ERROR logs/app.log) stores what the command prints.
  • Maths: $((n + 1)).
  • Condition: if [ $n -gt 2 ]; then … else … fi. Compare numbers with -eq -ne -gt -lt -ge -le, test files with -f (file exists) and -d (folder exists).
  • Loop: for f in logs/*.log; do … done.

Put "$var" in double quotes when it might contain spaces.

Definition

Command substitution

`$(command)` runs the command and puts what it printed in its place, so you can store it in a variable.

Exit status

Every command reports 0 for success and another number for failure. `if` runs the then-part when the test reports 0.

Examples

A health check

Run it in the lesson

Count errors, then decide what to say.

errors=$(grep -c ERROR logs/app.log)
echo "errors today: $errors"
if [ $errors -gt 2 ]; then
    echo "ALERT: too many errors"
else
    echo "all fine"
fi
Step by step
  1. L1grep prints 3, which goes into the variable errors.
  2. L2$errors is replaced by 3 inside the double quotes.errors today: 3
  3. L33 -gt 2 is true, so the then-part runs.ALERT: too many errors

Loop over files

Run it in the lesson

For each text file in notes, print its name and line count. A counter adds them up.

total=0
for f in notes/*.txt; do
    n=$(wc -l < $f)
    echo "$f: $n"
    total=$((total + n))
done
echo "total: $total"
Step by step
  1. L2notes/*.txt expands to ideas.txt and todo.txt, in alphabetical order.
  2. L3wc -l < file prints only the number, without the file name.
  3. L5Add to the running total.
  4. L73 + 3.total: 6

Common mistakes

Spaces around =

n = 3 runs a command called n. Write n=3.

Missing spaces inside [ ]

[$n -gt 2] fails; the brackets need spaces: [ $n -gt 2 ].

Quick quiz

1. What does this print?

n=0
for w in red green blue; do
    n=$((n + 1))
    echo "$n $w"
done
  1. A
    1 red
    2 green
    3 blue
  2. B
    0 red
    1 green
    2 blue
  3. C
    1 red
    1 green
    1 blue
Show the answer

Answer: A

n goes up by one before each echo.

2. What does this print?

if [ -f logs/app.log ]; then echo found; else echo missing; fi
if [ -d logs/app.log ]; then echo folder; else echo "not a folder"; fi
  1. A
    found
    not a folder
  2. B
    found
    folder
  3. C
    missing
    not a folder
Show the answer

Answer: A

app.log exists and is a file, not a folder.

Practice

3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.

  1. PredictFollow the script

    Type exactly what this prints.

  2. ModifyMake it a warning

    The script always prints the count. Change it so it prints WARN: 3 errors when there are more than 2 errors and OK: N errors otherwise.

  3. WriteBack up every note

    Make a folder backup. Then, with a for loop over notes/*.txt, copy each file into backup/ and print saved FILE for each one (FILE is the loop variable, e.g. saved notes/ideas.txt).

Practise this lesson

Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.

Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.

Terms in this lesson

TermChineseDefinition
Shell scriptshell 脚本A file of shell commands run one after another.
Shell variableshell 变量A name set with name=value and read with $name.
Exit status退出状态The number a command ends with: 0 means success.