The Power of Bash Scripting
Bash scripting is the most direct way to automate tasks on Linux systems. Every administrator needs to read, write, and debug shell scripts. While other languages offer more features, Bash's ubiquity and direct system integration make it indispensable.
This guide takes you from basic concepts to advanced techniques used in production scripts.
Script Fundamentals
Your First Script
#!/bin/bash
# Description: A simple greeting script
echo "Hello, $(whoami)!"
echo "Today is $(date +%Y-%m-%d)"
echo "You are on $(hostname)"
The shebang (#!/bin/bash) tells the system which interpreter to use. Always include it.
Variables
#!/bin/bash
# Declaring variables (no spaces around =)
NAME="Linux Server"
COUNT=42
# Using variables
echo "Server: $NAME"
echo "Count: ${COUNT}"
# Command substitution
CURRENT_DATE=$(date +%Y-%m-%d)
USERS=$(who | wc -l)
echo "Date: $CURRENT_DATE, Users logged in: $USERS"
Control Structures
Conditionals
#!/bin/bash
FILE="/etc/passwd"
if [[ -f "$FILE" ]]; then
echo "$FILE exists"
elif [[ -d "$FILE" ]]; then
echo "$FILE is a directory"
else
echo "$FILE not found"
fi
# Numeric comparisons
if [[ $COUNT -gt 10 ]]; then
echo "Count is greater than 10"
fi
# String comparisons
if [[ "$NAME" == "Linux Server" ]]; then
echo "Name matches"
fi
Loops
#!/bin/bash
# For loop with list
for server in web1 web2 db1 db2; do
echo "Checking $server..."
ping -c 1 "$server" > /dev/null && echo " $server is up"
done
# For loop with range
for i in {1..5}; do
echo "Iteration $i"
done
# While loop
COUNT=0
while [[ $COUNT -lt 5 ]]; do
echo "Count: $COUNT"
((COUNT++))
done
# Reading file line by line
while IFS= read -r line; do
echo "Line: $line"
done < /etc/hosts
Functions
#!/bin/bash
# Function definition
log_message() {
local level="$1"
local message="$2"
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] [$level] $message"
}
check_service() {
local service="$1"
if systemctl is-active --quiet "$service"; then
log_message "INFO" "$service is running"
return 0
else
log_message "ERROR" "$service is not running"
return 1
fi
}
# Using functions
log_message "INFO" "Script started"
check_service "nginx"
check_service "postgresql"
log_message "INFO" "Script completed"
Input and Arguments
#!/bin/bash
# Positional arguments
echo "Script name: $0"
echo "First argument: $1"
echo "All arguments: $@"
echo "Number of arguments: $#"
# Processing with getopts
while getopts "v:f:h" opt; do
case $opt in
v) VERBOSE="$OPTARG" ;;
f) FILE="$OPTARG" ;;
h) echo "Usage: $0 [-v level] [-f file]"; exit 0 ;;
*) echo "Invalid option"; exit 1 ;;
esac
done
# Interactive input
read -p "Enter your name: " USER_NAME
read -sp "Enter password: " PASSWORD
echo # New line after password
Error Handling
#!/bin/bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Trap for cleanup
cleanup() {
echo "Cleaning up..."
rm -f /tmp/tempfile.$$
}
trap cleanup EXIT
# Error handling function
die() {
echo "ERROR: $1" >&2
exit "${2:-1}"
}
# Usage
[[ -f "$CONFIG_FILE" ]] || die "Config file not found" 2
Text Processing
#!/bin/bash
# Using grep, awk, sed together
# Find failed SSH logins
grep "Failed password" /var/log/auth.log | \
awk '{print $11}' | \
sort | uniq -c | sort -rn | head -10
# Extract and transform data
cat /etc/passwd | \
awk -F: '$3 >= 1000 {print $1, $6}' | \
while read user home; do
echo "User: $user, Home: $home"
done
Best Practices
- Always quote variables: "$VAR" not $VAR
- Use [[ ]] over [ ] for conditionals
- Enable strict mode: set -euo pipefail
- Use shellcheck to validate scripts
- Add comments explaining complex logic
- Use functions for reusable code
Conclusion
Bash scripting is a fundamental skill for Linux administrators. Master these concepts, and you'll automate tasks efficiently while maintaining readable, maintainable scripts.
Our Bash scripting eBooks offer comprehensive coverage with extensive exercises to build real-world automation skills.