
Bash Scripting for Beginners: Loops, Functions and Real Admin Scripts
Part 3 turns small scripts into useful admin tools. You will learn for loops, while loops, arrays, functions, logging and practical scripts for services, disk usage and DNS checks.
For loops
A for loop repeats commands for each item in a list.
for file in *.log; do
echo "$file"
done
Arrays are a clean way to store lists.
SERVICES=("nginx" "mysql" "sshd")
for SERVICE in "${SERVICES[@]}"; do
echo "$SERVICE"
done
Read a file line by line with while
This pattern is useful when reading a list of domains, users or paths.
while IFS= read -r DOMAIN; do
echo "Checking $DOMAIN"
done < domains.txt
Bash functions
Functions let you reuse blocks of logic.
check_service() {
local service="$1"
if systemctl is-active --quiet "$service"; then
echo "[OK] $service is running"
else
echo "[WARN] $service is not running"
fi
}
Add simple logging to scripts
log_msg() {
echo "[$(date -Is)] $*"
}
log_msg "Starting checks"
To log to a file as well as the terminal, use tee.
log_msg "Backup completed" | tee -a /var/log/my-script.log
Using set -euo pipefail carefully
You will often see this near the top of Bash scripts:
set -euo pipefail
| Option | Meaning |
|---|---|
-e | Exit if a command fails. |
-u | Treat unset variables as an error. |
-o pipefail | Fail a pipeline if any command in it fails. |
Script 1: check multiple services
#!/usr/bin/env bash
SERVICES=("nginx" "mysql" "sshd")
check_service() {
local service="$1"
if systemctl is-active --quiet "$service"; then
echo "[OK] $service is running"
else
echo "[WARN] $service is not running"
fi
}
for service in "${SERVICES[@]}"; do
check_service "$service"
done
[OK] nginx is running
[WARN] mysql is not running
[OK] sshd is runningWhat the multiple services script is doing
| Line | Meaning |
|---|---|
SERVICES=("nginx" "mysql" "sshd") | Creates a Bash array containing service names. |
check_service() { ... } | Defines a reusable function. |
local service="$1" | Stores the function's first argument in a local variable. |
for service in "${SERVICES[@]}" | Loops safely through every item in the array. |
check_service "$service" | Runs the function for each service. |
Script 2: warn when disk usage is high
#!/usr/bin/env bash
THRESHOLD=85
MOUNT="/"
usage="$(df "$MOUNT" | awk 'NR==2 {gsub(/%/,"",$5); print $5}')"
if [ "$usage" -ge "$THRESHOLD" ]; then
echo "[WARN] Disk usage on $MOUNT is ${usage}%"
exit 1
else
echo "[OK] Disk usage on $MOUNT is ${usage}%"
exit 0
fi
[OK] Disk usage on / is 55%For deeper disk checks, use the Linux High Disk Usage Troubleshooting Guide.
Script 3: check DNS for multiple domains
Create a file named domains.txt:
example.com
commandlinequiz.com
example.org
Then create the script:
#!/usr/bin/env bash
while IFS= read -r DOMAIN; do
[ -z "$DOMAIN" ] && continue
echo "== $DOMAIN =="
dig +short "$DOMAIN"
echo
done < domains.txt
== example.com ==
93.184.216.34
== commandlinequiz.com ==
104.21.10.123
172.67.150.45
== example.org ==
93.184.216.34For more DNS examples, see the dig command guide.
Practice exercises
Exercise 1: add another service
Add redis or httpd to the SERVICES array and run the script again.
Exercise 2: write output to a log file
Update the service checker so the output is also appended to /tmp/service-check.log.
./check-services.sh | tee -a /tmp/service-check.log
Exercise 3: check domains from a file
Add more domains to domains.txt and confirm your DNS checker loops through each one.
Download the example scripts
Check scripts before using them on a server
bash -n check-services.sh
shellcheck check-services.sh
When the script changes files or restarts services, test it on a safe machine first. Production servers are not the place for “let’s see what happens”.
Where to go next
- Use the Bash Scripting Cheat Sheet as a quick reference.
- Test snippets with the Bash Checker.
- Build real troubleshooting scripts using the Linux Troubleshooting Hub.
- Practise Linux admin topics with the Linux+ Practice Quiz.
Combine loops and functions for cleaner scripts
Once a script grows beyond a few lines, functions make it easier to read and reuse.
#!/usr/bin/env bash
check_service() {
local service="$1"
if systemctl is-active --quiet "$service"; then
echo "OK: $service is running"
else
echo "ERROR: $service is not running"
fi
}
for service in nginx mariadb sshd; do
check_service "$service"
done
OK: nginx is running
OK: mariadb is running
ERROR: sshd is not runningDeepen the Bash topics from Part 3
Read the focused guides for for loops, while loops, functions and the Bash Scripting Hub.
Frequently Asked Questions
When should I use Bash functions?
Use functions when a block of commands has a clear job or needs to be reused.
Can Bash loops call functions?
Yes. A common pattern is to loop through a list and call a function for each item.
How do I keep Bash scripts readable?
Use clear variable names, functions, comments for intent and small sections that do one job.
What should I learn after beginner Bash scripting?
Learn loops, functions, exit codes, logging, cron or systemd timers and safer input handling.