Practical Examples
Overview
This chapter demonstrates how to apply the knowledge learned earlier to daily work through practical examples.
System Management Scripts
System Information Report
bash
#!/bin/bash
# system-info.sh - System information report script
echo "======================================"
echo " System Information Report"
echo " $(date '+%Y-%m-%d %H:%M:%S')"
echo "======================================"
echo -e "\n[System Information]"
echo "Hostname: $(hostname)"
echo "System: $(uname -s) $(uname -r)"
echo "Architecture: $(uname -m)"
echo "Uptime: $(uptime -p)"
echo -e "\n[CPU Information]"
echo "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2)"
echo "Cores: $(nproc)"
echo "Load: $(cat /proc/loadavg | awk '{print $1, $2, $3}')"
echo -e "\n[Memory Information]"
free -h | awk 'NR==2{printf "Total: %s, Used: %s, Available: %s\n", $2, $3, $7}'
echo -e "\n[Disk Usage]"
df -h | grep -E '^/dev' | awk '{printf "%-15s %s Used (%s)\n", $1, $3, $5}'
echo -e "\n[Network Interfaces]"
ip -4 addr show | grep -E 'inet ' | awk '{print $NF": "$2}'
echo -e "\n[Logged In Users]"
who | awk '{print $1" from "$5" logged in at "$3" "$4}'Log Cleanup Script
bash
#!/bin/bash
# clean-logs.sh - Clean old log files
LOG_DIR="/var/log"
DAYS=30
DRY_RUN=false
# Parse arguments
while getopts "d:n" opt; do
case $opt in
d) DAYS=$OPTARG ;;
n) DRY_RUN=true ;;
*) echo "Usage: $0 [-d days] [-n dry-run]"; exit 1 ;;
esac
done
echo "Cleaning log files older than $DAYS days..."
echo "Directory: $LOG_DIR"
echo "Dry run: $DRY_RUN"
echo
# Find old logs
files=$(find "$LOG_DIR" -type f -name "*.log*" -mtime +$DAYS 2>/dev/null)
if [ -z "$files" ]; then
echo "No files found to clean"
exit 0
fi
total_size=0
count=0
while IFS= read -r file; do
size=$(du -b "$file" 2>/dev/null | cut -f1)
total_size=$((total_size + size))
count=$((count + 1))
if [ "$DRY_RUN" = true ]; then
echo "[Dry run] Would delete: $file ($(du -h "$file" | cut -f1))"
else
rm -f "$file"
echo "Deleted: $file"
fi
done <<< "$files"
echo
echo "Total $count files, $(numfmt --to=iec $total_size)"Batch User Creation
bash
#!/bin/bash
# create-users.sh - Batch user creation
# User list file format: username:password:group
USER_FILE="users.txt"
if [ ! -f "$USER_FILE" ]; then
echo "Error: $USER_FILE not found"
exit 1
fi
while IFS=: read -r username password group; do
# Skip comments and empty lines
[[ "$username" =~ ^#.*$ || -z "$username" ]] && continue
# Check if user exists
if id "$username" &>/dev/null; then
echo "User $username already exists, skipping"
continue
fi
# Create group (if doesn't exist)
if ! getent group "$group" &>/dev/null; then
groupadd "$group"
echo "Created group: $group"
fi
# Create user
useradd -m -g "$group" -s /bin/bash "$username"
echo "$username:$password" | chpasswd
# Force password change on first login
chage -d 0 "$username"
echo "Created user: $username (group: $group)"
done < "$USER_FILE"
echo "Done!"Backup Scripts
Incremental Backup Script
bash
#!/bin/bash
# incremental-backup.sh - Incremental backup script
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www"
SNAPSHOT_FILE="${BACKUP_DIR}/.snapshot"
DATE=$(date +%Y%m%d)
mkdir -p "$BACKUP_DIR"
# Determine backup type
if [ ! -f "$SNAPSHOT_FILE" ]; then
# Full backup
BACKUP_FILE="${BACKUP_DIR}/full_${DATE}.tar.gz"
echo "Performing full backup..."
tar -czf "$BACKUP_FILE" -g "$SNAPSHOT_FILE" "$SOURCE_DIR"
else
# Incremental backup
BACKUP_FILE="${BACKUP_DIR}/incr_${DATE}_$(date +%H%M%S).tar.gz"
echo "Performing incremental backup..."
tar -czf "$BACKUP_FILE" -g "$SNAPSHOT_FILE" "$SOURCE_DIR"
fi
if [ $? -eq 0 ]; then
echo "Backup successful: $BACKUP_FILE"
echo "Size: $(du -h "$BACKUP_FILE" | cut -f1)"
else
echo "Backup failed!"
exit 1
fi
# Clean backups older than 30 days
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
echo "Cleaned old backups"Database Backup
bash
#!/bin/bash
# mysql-backup.sh - MySQL database backup
DB_USER="backup_user"
DB_PASS="password"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
mkdir -p "$BACKUP_DIR"
# Get all databases
databases=$(mysql -u"$DB_USER" -p"$DB_PASS" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|sys)")
for db in $databases; do
BACKUP_FILE="${BACKUP_DIR}/${db}_${DATE}.sql.gz"
echo "Backing up database: $db"
mysqldump -u"$DB_USER" -p"$DB_PASS" --single-transaction "$db" | gzip > "$BACKUP_FILE"
if [ ${PIPESTATUS[0]} -eq 0 ]; then
echo " Success: $BACKUP_FILE ($(du -h "$BACKUP_FILE" | cut -f1))"
else
echo " Failed: $db"
fi
done
# Clean old backups
echo "Cleaning backups older than $RETENTION_DAYS days..."
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup complete!"Monitoring Scripts
Disk Space Monitoring
bash
#!/bin/bash
# disk-monitor.sh - Disk space monitoring
THRESHOLD=80
ALERT_EMAIL="admin@example.com"
check_disk() {
df -h | grep -E '^/dev' | while read -r line; do
partition=$(echo "$line" | awk '{print $1}')
usage=$(echo "$line" | awk '{print $5}' | tr -d '%')
mount_point=$(echo "$line" | awk '{print $6}')
if [ "$usage" -ge "$THRESHOLD" ]; then
echo "Warning: $mount_point ($partition) usage ${usage}%"
# Send email alert
if command -v mail &>/dev/null; then
echo "Disk alert: $mount_point usage ${usage}%" | \
mail -s "Disk Space Alert - $(hostname)" "$ALERT_EMAIL"
fi
fi
done
}
echo "Disk space check - $(date)"
echo "Alert threshold: ${THRESHOLD}%"
echo "========================"
check_diskService Monitoring
bash
#!/bin/bash
# service-monitor.sh - Service monitoring script
SERVICES=("nginx" "mysql" "redis")
LOG_FILE="/var/log/service-monitor.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_and_restart() {
local service=$1
if ! systemctl is-active --quiet "$service"; then
log "Warning: $service is stopped, attempting restart..."
systemctl restart "$service"
sleep 5
if systemctl is-active --quiet "$service"; then
log "Success: $service restarted"
else
log "Error: $service restart failed!"
fi
fi
}
log "Starting service check..."
for service in "${SERVICES[@]}"; do
check_and_restart "$service"
done
log "Service check complete"Log Analysis
Web Log Analysis
bash
#!/bin/bash
# analyze-access-log.sh - Analyze Nginx access logs
LOG_FILE="/var/log/nginx/access.log"
TOP_N=10
echo "=== Web Log Analysis ==="
echo "Log file: $LOG_FILE"
echo "Analysis time: $(date)"
echo
echo "--- Top $TOP_N IPs by visit count ---"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -n $TOP_N
echo
echo "--- Top $TOP_N visited pages ---"
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -n $TOP_N
echo
echo "--- HTTP status code statistics ---"
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -rn
echo
echo "--- Hourly visit counts ---"
awk '{print $4}' "$LOG_FILE" | cut -d: -f2 | sort | uniq -c
echo
echo "--- Traffic statistics ---"
total_bytes=$(awk '{sum += $10} END {print sum}' "$LOG_FILE")
echo "Total traffic: $(numfmt --to=iec $total_bytes 2>/dev/null || echo "$total_bytes bytes")"Deployment Scripts
Simple Deployment Script
bash
#!/bin/bash
# deploy.sh - Application deployment script
APP_NAME="myapp"
DEPLOY_DIR="/var/www/$APP_NAME"
REPO_URL="git@github.com:user/myapp.git"
BRANCH="main"
BACKUP_DIR="/backup/deployments"
set -e # Exit on error
log() {
echo "[$(date '+%H:%M:%S')] $1"
}
# Create backup
backup() {
if [ -d "$DEPLOY_DIR" ]; then
local backup_file="${BACKUP_DIR}/${APP_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz"
mkdir -p "$BACKUP_DIR"
log "Creating backup: $backup_file"
tar -czf "$backup_file" -C "$(dirname $DEPLOY_DIR)" "$(basename $DEPLOY_DIR)"
fi
}
# Pull code
pull_code() {
if [ -d "$DEPLOY_DIR/.git" ]; then
log "Updating code..."
cd "$DEPLOY_DIR"
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"
else
log "Cloning repository..."
git clone -b "$BRANCH" "$REPO_URL" "$DEPLOY_DIR"
fi
}
# Install dependencies
install_deps() {
cd "$DEPLOY_DIR"
if [ -f "package.json" ]; then
log "Installing Node.js dependencies..."
npm install --production
elif [ -f "requirements.txt" ]; then
log "Installing Python dependencies..."
pip install -r requirements.txt
fi
}
# Restart service
restart_service() {
log "Restarting service..."
systemctl restart "$APP_NAME"
}
# Main flow
main() {
log "Starting deployment of $APP_NAME..."
backup
pull_code
install_deps
restart_service
log "Deployment complete!"
}
mainUseful One-Liners
bash
# Find large files
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
# Count lines of code
find . -name "*.py" | xargs wc -l | tail -1
# Batch rename files
for f in *.txt; do mv "$f" "${f%.txt}.md"; done
# Monitor command output changes
watch -n 1 "ss -s"
# Find and delete empty directories
find . -type d -empty -delete
# Show directory sizes sorted
du -sh */ | sort -h
# Find recently modified files
find . -type f -mtime -1 -ls
# Batch compress images
for f in *.jpg; do convert "$f" -quality 80 "compressed_$f"; done
# Generate random password
openssl rand -base64 16
# Check if port is open
timeout 1 bash -c '</dev/tcp/localhost/80' && echo "Open" || echo "Closed"Summary
This chapter demonstrated multiple practical Shell script examples:
- System Management: Information reports, log cleanup, user management
- Backup Scripts: Incremental backups, database backups
- Monitoring Scripts: Disk monitoring, service monitoring
- Log Analysis: Web log statistics
- Deployment Scripts: Automated deployment
These scripts can be modified and extended according to actual needs. Through practice, you will better master Shell scripting.
Previous: Environment Variables
Back: Index