Introduction
This lesson is about small shell scripts.
The main question is:
How do you turn repeated shell commands into a simple script that makes decisions, loops, checks results, and runs safely?
What you should be able to do after this lesson:
- Write a simple shell script with a shebang.
- Use variables, tests, loops, and command substitution.
- Understand exit status,
&&, and||. - Read input with
read. - Understand where scripts live and how execution permission works.
- Recognize why suid scripts are a special case and usually avoided.
Big Idea: A Shell Script Is Just Commands Plus Logic
A shell script is not magic. It is a text file that the shell interprets as a list of commands.
At beginner level, keep this picture:
commands -> variables -> tests -> loops -> exit status
That is enough to understand most LPIC-1 shell scripting questions.
Start with the Shebang
The first line often tells the system which interpreter to use.
Example:
#!/bin/bash
This matters because:
- it makes the script intent clear
- it helps the system run the script with the right interpreter
Make the Script Executable
chmod u+x script.sh
./script.sh
Simple rule:
- executable bit allows direct execution
./means "run this file from the current directory"
Variables
Example:
name="linux"
echo "$name"
Use quotes around expansions when possible. It prevents many whitespace problems.
Command Substitution
This means "run a command and capture its output".
Example:
today="$(date +%F)"
echo "$today"
This is one of the most useful scripting patterns in shell work.
Tests and Exit Status
Commands return an exit status.
Simple rule:
0usually means success- non-zero usually means failure
Test example:
if test -f /etc/passwd; then
echo "file exists"
fi
Equivalent bracket form:
if [ -f /etc/passwd ]; then
echo "file exists"
fi
if
Example:
if [ "$1" = "start" ]; then
echo "starting"
else
echo "unknown action"
fi
This is how scripts make simple decisions.
Loops
for
for n in 1 2 3; do
echo "$n"
done
With seq:
for n in $(seq 1 3); do
echo "$n"
done
while
count=1
while [ "$count" -le 3 ]; do
echo "$count"
count=$((count + 1))
done
read
Read user input:
read -r name
echo "Hello, $name"
This is useful for simple interactive scripts.
Chained Commands
Run next command only if the first one succeeds
mkdir backup && cp file.txt backup/
Run fallback when the first one fails
cp file.txt /tmp/ || echo "copy failed"
This works because the shell checks exit status.
Conditional Mail to the Superuser
LPIC mentions this because scripts often need a simple alert path.
Very small idea:
- if a job fails, notify
root
Example:
backup-command || mail -s "Backup failed" root
You do not need deep mail configuration here. Just understand the pattern.
Script Location, Ownership, and Rights
Common places:
- personal scripts in
~/bin - admin scripts in
/usr/local/bin
Basic rule:
- keep scripts in a sensible location
- give execute permission only when needed
- avoid treating shell scripts like compiled privileged binaries
About suid scripts
LPIC expects awareness of suid rights for scripts.
Important beginner truth:
- suid shell scripts are usually avoided
- many systems ignore or restrict them for security reasons
So the practical lesson is:
- know the term
- do not assume suid scripts are a normal safe admin pattern
exec
exec replaces the current shell process with another command.
Example:
exec sleep 10
This is more awareness-level here than everyday beginner scripting.
A Very Small Example Script
#!/bin/bash
target="$1"
if [ -z "$target" ]; then
echo "usage: $0 <directory>"
exit 1
fi
if [ -d "$target" ]; then
echo "directory exists"
else
echo "directory missing"
fi
Practice Step by Step
1) Write a script with a shebang
- Create
hello.sh. - Add:
#!/bin/bashecho "hello" - Make it executable:
chmod u+x hello.sh - Run it:
./hello.sh
2) Use a test and `if`
- Write a script that checks:
[ -f /etc/passwd ] - Print one message for "exists".
- Print another message for "missing".
3) Use command substitution
- Set:
today="$(date +%F)" - Print it with
echo. - Notice that the variable contains command output, not the literal command text.
Cheat Sheet
#!/bin/bash= choose script interpreterchmod u+x script.sh= make script executable- variables =
name=value - command substitution =
var="$(command)" testor[ ... ]= check a conditionif= conditional logicfor,while= loopsread -r= read user input&&= continue on success||= fallback on failureexec= replace current shell with another command- suid shell scripts = awareness topic, usually avoided in practice
Test Your Knowledge
Complete the quiz to assess your understanding of this course's concepts.
