Shell Scripting
Learn how to automate Linux tasks using Bash scripts and understand why shell scripting is one of the most important Linux skills for DevOps and system administration.
Difficulty: Beginner
Estimated reading time: 75 min
Introduction
At some point while using Linux, repetitive tasks start becoming annoying.
Examples:
- creating backups
- restarting services
- cleaning logs
- deploying applications
- checking disk usage
- monitoring servers
Doing everything manually does not scale.
This is where scripting becomes powerful.
Shell scripting allows you to:
- automate commands
- combine tools together
- create reusable workflows
- manage servers efficiently
- automate infrastructure
One of the biggest reasons Linux dominates servers and DevOps is:
Automation.
And shell scripting is one of the foundations of Linux automation.
What Is a Shell Script?
A shell script is simply:
A file containing Linux commands.
Instead of typing commands manually one by one:
pwd
ls
date
you place them inside a file:
#!/bin/bash
pwd
ls
date
and execute the file.
The shell reads commands sequentially and executes them automatically.
Why Bash?
There are many Linux shells:
| Shell | Description |
|---|---|
| Bash | Most common |
| Zsh | Modern interactive shell |
| Fish | User-friendly shell |
| Dash | Lightweight shell |
For scripting, Bash is the most common beginner choice.
Bash stands for:
Bourne Again Shell
Your First Script
Creating a Script
Create file:
vim hello.sh
Press:
i
to enter insert mode and add:
#!/bin/bash
echo "Hello Linux"
Then press:
ESC
and save + quit using:
:wq
Understanding the Shebang
First line:
#!/bin/bash
called:
Shebang.
It tells Linux:
Which interpreter should execute the script.
In this case:
/bin/bash
Making Scripts Executable
Before execution:
chmod +x hello.sh
This adds execute permissions.
Running the Script
Execute:
./hello.sh
Output:
Hello Linux
Why ./ Is Needed
Linux does not automatically search the current directory.
This is intentional for security reasons.
So:
./script.sh
means:
Execute file from current directory.
Variables
Creating Variables
Example:
NAME="John"
Access variable:
echo $NAME
Output:
John
Important Syntax Rule
Correct:
NAME="John"
Incorrect:
NAME = "John"
Spaces break Bash variable assignment.
This confuses many beginners.
Variables Store Data
Variables can store:
- text
- numbers
- paths
- command output
Example:
FILE="/var/log/syslog"
Using Variables
Example:
LOG_FILE="/var/log/syslog"
echo "Reading $LOG_FILE"
Reading User Input
read Command
Example:
echo "What is your name?"
read NAME
echo "Hello $NAME"
This makes scripts interactive.
Prompt Inline
Cleaner syntax:
read -p "Enter your name: " NAME
Command Substitution
Capturing Command Output
Example:
DATE=$(date)
Now:
echo $DATE
contains command output.
Real Example
CURRENT_USER=$(whoami)
echo "Logged in as $CURRENT_USER"
Very common in scripts.
Conditions
Basic if Statement
Example:
if [ 5 -gt 3 ]; then
echo "True"
fi
Understanding Syntax
| Part | Meaning |
|---|---|
if |
Start condition |
[ ] |
Test expression |
then |
Execute block |
fi |
End if |
fi is simply:
if backwards
Comparison Operators
| Operator | Meaning |
|---|---|
-eq |
Equal |
-ne |
Not equal |
-gt |
Greater than |
-lt |
Less than |
-ge |
Greater or equal |
-le |
Less or equal |
String Comparison
Example:
NAME="john"
if [ "$NAME" = "john" ]; then
echo "Welcome"
fi
Why Quotes Matter
Safer:
"$NAME"
Without quotes, empty variables may break conditions.
This becomes important in production scripts.
if / else
Example:
if [ "$USER" = "root" ]; then
echo "Running as root"
else
echo "Not root"
fi
elif
Example:
if [ "$ENV" = "dev" ]; then
echo "Development"
elif [ "$ENV" = "prod" ]; then
echo "Production"
else
echo "Unknown"
fi
File Conditions
Check If File Exists
Example:
if [ -f "/etc/passwd" ]; then
echo "File exists"
fi
Common File Tests
| Test | Meaning |
|---|---|
-f |
File exists |
-d |
Directory exists |
-r |
Readable |
-w |
Writable |
-x |
Executable |
Real Example
if [ -d "/var/log" ]; then
echo "Log directory exists"
fi
Loops
for Loop
Example:
for NAME in John Mike Anna
do
echo $NAME
done
Output:
John
Mike
Anna
Loop Through Files
Example:
for FILE in *.txt
do
echo $FILE
done
Very common in automation.
while Loop
Example:
COUNT=1
while [ $COUNT -le 5 ]
do
echo $COUNT
COUNT=$((COUNT + 1))
done
Arithmetic
Simple Arithmetic
Example:
NUM=$((5 + 3))
echo $NUM
Output:
8
Increment Example
COUNT=$((COUNT + 1))
Very common in loops.
Functions
Creating Functions
Example:
greet() {
echo "Hello $1"
}
Call function:
greet John
Output:
Hello John
Understanding Parameters
Inside functions:
| Variable | Meaning |
|---|---|
$1 |
First argument |
$2 |
Second argument |
$@ |
All arguments |
Real Example
backup() {
cp $1 $2
}
Usage:
backup file.txt backup.txt
Exit Codes
Every Command Returns a Status
Linux commands return exit codes.
| Code | Meaning |
|---|---|
0 |
Success |
| non-zero | Error |
Checking Exit Status
Example:
ls file.txt
echo $?
$? contains the previous command status.
Real Example
if [ $? -eq 0 ]; then
echo "Success"
else
echo "Failed"
fi
Very important in automation.
Useful Script Arguments
Accessing Script Arguments
Script:
#!/bin/bash
echo $1
Run:
./script.sh hello
Output:
hello
Useful Special Variables
| Variable | Meaning |
|---|---|
$0 |
Script name |
$1 |
First argument |
$# |
Number of arguments |
$@ |
All arguments |
Real-World Examples
Backup Script
#!/bin/bash
SOURCE="/home/user/files"
BACKUP="/backup/files"
cp -r $SOURCE $BACKUP
echo "Backup completed"
Disk Space Monitor
#!/bin/bash
USAGE=$(df / | tail -1 | awk '{print $5}')
echo "Disk usage: $USAGE"
Service Checker
#!/bin/bash
systemctl is-active nginx
if [ $? -eq 0 ]; then
echo "Nginx is running"
else
echo "Nginx is down"
fi
This resembles real server monitoring.
Debugging Scripts
Enable Debug Mode
bash -x script.sh
Displays executed commands step-by-step.
Very useful during troubleshooting.
Common Beginner Mistakes
Missing Execute Permission
Problem:
Permission denied
Fix:
chmod +x script.sh
Wrong Shebang
Incorrect interpreter path may break scripts.
Missing Quotes
Dangerous:
if [ $NAME = john ]
Safer:
if [ "$NAME" = "john" ]
Spaces Around =
Incorrect:
NAME = John
Correct:
NAME=John
Why Shell Scripting Matters for DevOps
Shell scripting is everywhere in infrastructure.
Examples:
| Technology | Uses Shell Scripts? |
|---|---|
| Docker entrypoints | Yes |
| CI/CD pipelines | Yes |
| Deployment automation | Yes |
| Kubernetes init scripts | Yes |
| Server maintenance | Yes |
Even modern cloud systems still rely heavily on shell automation.
Bash vs Programming Languages
Bash is excellent for:
- automation
- orchestration
- file operations
- Linux administration
But less ideal for:
- large applications
- complex logic
- web backends
This is why DevOps engineers often combine:
- Bash
- Python
- Go
together.
Linux Philosophy and Automation
Shell scripting reflects core Unix philosophy:
- small tools
- composability
- automation
- text-based workflows
Linux systems were designed to be scriptable from the beginning.
This is one reason Linux became dominant in servers and infrastructure.
The Bigger Picture
Once you understand shell scripting, Linux changes completely.
You stop being just a user of the operating system.
You start becoming:
Someone who automates the operating system.
This shift is incredibly important in:
- DevOps
- cloud engineering
- infrastructure automation
- backend systems
- cybersecurity
Shell scripting is often the first real step into infrastructure engineering.
What Comes Next
In the next chapter, we will explore:
- cron jobs
- scheduled tasks
- timers
- automation scheduling
- background execution
- recurring Linux jobs
This is where Linux automation becomes continuous.