Introduction to Bash Scripting
Bash (Bourne Again Shell) scripting is a powerful way to automate tasks, streamline workflows, and create complex programs using the command line. Whether you're a system administrator, developer, or power user, learning Bash scripting will significantly boost your productivity.
"Automation is the key to efficiency. A well-written Bash script can save you hours of repetitive work and reduce human errors."
Getting Started with Your First Script
Every Bash script starts with a shebang line that tells the system which interpreter to use:
Hello World Script
#!/bin/bash # This is a comment echo "Hello, World!" echo "Welcome to Bash scripting!"
Welcome to Bash scripting!
To make your script executable and run it:
# Make script executable chmod +x hello.sh # Run the script ./hello.sh
Variables and Data Types
Bash variables store data that can be used throughout your script. Variable names are case-sensitive and should not contain spaces.
Variable Declaration
# Variable assignment (no spaces around =)
name="John"
age=25
today=$(date)
# Using variables
echo "Name: $name"
echo "Age: ${age}"
Special Variables
# Command line arguments echo "Script name: $0" echo "First argument: $1" echo "All arguments: $@" echo "Number of arguments: $#"
Reading User Input
Interactive Script
#!/bin/bash echo "What's your name?" read name echo "How old are you?" read age echo "Hello $name! You are $age years old."
Conditional Statements
Conditional statements allow your scripts to make decisions based on different conditions:
If-Else Statements
Basic Conditional
#!/bin/bash
read -p "Enter a number: " number
if [ $number -gt 10 ]; then
echo "Number is greater than 10"
elif [ $number -eq 10 ]; then
echo "Number is exactly 10"
else
echo "Number is less than 10"
fi
Comparison Operators
Numeric Comparisons
-eq: Equal to-ne: Not equal to-gt: Greater than-lt: Less than-ge: Greater than or equal-le: Less than or equal
String Comparisons
=: Equal to!=: Not equal to-z: String is empty-n: String is not empty
File Tests
File Checking Script
#!/bin/bash
file="example.txt"
if [ -f "$file" ]; then
echo "File exists"
if [ -r "$file" ]; then
echo "File is readable"
fi
if [ -w "$file" ]; then
echo "File is writable"
fi
if [ -x "$file" ]; then
echo "File is executable"
fi
else
echo "File does not exist"
fi
Loops for Repetitive Tasks
For Loops
Basic For Loop
#!/bin/bash
# Loop through a list
for fruit in apple banana cherry; do
echo "I like $fruit"
done
# Loop through numbers
for i in {1..5}; do
echo "Count: $i"
done
# Loop through files
for file in *.txt; do
echo "Processing $file"
done
While Loops
While Loop Example
#!/bin/bash
counter=1
while [ $counter -le 5 ]; do
echo "Iteration: $counter"
counter=$((counter + 1))
done
# Reading file line by line
while IFS= read -r line; do
echo "Line: $line"
done < "input.txt"
Functions for Code Reusability
Functions help organize your code and make it reusable:
Function Definition and Usage
#!/bin/bash
# Function definition
greet() {
local name=$1
local age=$2
echo "Hello $name! You are $age years old."
}
# Function with return value
is_even() {
local number=$1
if [ $((number % 2)) -eq 0 ]; then
return 0 # true
else
return 1 # false
fi
}
# Using functions
greet "Alice" 30
number=42
if is_even $number; then
echo "$number is even"
else
echo "$number is odd"
fi
Arrays and String Manipulation
Working with Arrays
Array Operations
#!/bin/bash
# Array declaration
fruits=("apple" "banana" "cherry" "date")
# Access elements
echo "First fruit: ${fruits[0]}"
echo "All fruits: ${fruits[@]}"
echo "Number of fruits: ${#fruits[@]}"
# Add elements
fruits+=("elderberry")
# Loop through array
for fruit in "${fruits[@]}"; do
echo "Processing: $fruit"
done
String Manipulation
String Operations
#!/bin/bash
text="Hello World"
# String length
echo "Length: ${#text}"
# Substring extraction
echo "Substring: ${text:0:5}" # First 5 characters
# String replacement
echo "Replace: ${text/World/Universe}"
# Convert case
echo "Uppercase: ${text^^}"
echo "Lowercase: ${text,,}"
Error Handling and Debugging
Exit Codes and Error Handling
Robust Error Handling
#!/bin/bash
# Exit on any error
set -e
# Function to handle errors
error_exit() {
echo "Error: $1" >&2
exit 1
}
# Check if file exists before processing
if [ ! -f "input.txt" ]; then
error_exit "Input file not found"
fi
# Command with error checking
if ! cp "source.txt" "destination.txt"; then
error_exit "Failed to copy file"
fi
echo "Script completed successfully"
Debugging Techniques
# Run script with debugging bash -x script.sh # Add debugging to script set -x # Enable debugging # ... your code ... set +x # Disable debugging
Practical Script Examples
System Backup Script
Automated Backup
#!/bin/bash
# Configuration
SOURCE_DIR="/home/user/documents"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="backup_$DATE.tar.gz"
# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Create compressed backup
echo "Creating backup..."
if tar -czf "$BACKUP_DIR/$BACKUP_NAME" "$SOURCE_DIR"; then
echo "Backup created: $BACKUP_DIR/$BACKUP_NAME"
# Remove backups older than 7 days
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete
echo "Old backups cleaned up"
else
echo "Backup failed!" >&2
exit 1
fi
Log File Monitor
Log Monitoring Script
#!/bin/bash
LOG_FILE="/var/log/application.log"
ERROR_PATTERN="ERROR|CRITICAL"
EMAIL="admin@example.com"
# Monitor log file for errors
tail -f "$LOG_FILE" | while read line; do
if echo "$line" | grep -E "$ERROR_PATTERN" > /dev/null; then
echo "Error detected: $line"
# Send alert (requires mail command)
echo "Error in application: $line" | mail -s "Application Error Alert" "$EMAIL"
fi
done
Best Practices and Tips
- Use meaningful variable names:
user_countinstead ofuc - Quote your variables: Use
"$variable"to handle spaces - Check exit codes: Always verify command success
- Use functions: Break complex scripts into smaller functions
- Add comments: Explain complex logic and purpose
- Use shellcheck: Install and use shellcheck for script validation
- Handle edge cases: Check for file existence, empty variables, etc.
Common Pitfalls to Avoid
Variable Assignment
# Wrong name = "John" # Correct name="John"
Unquoted Variables
# Wrong (fails with spaces) if [ $name = "John Doe" ] # Correct if [ "$name" = "John Doe" ]
Conclusion
Bash scripting is an invaluable skill that can dramatically improve your efficiency in Linux environments. Start with simple scripts and gradually incorporate more advanced features like functions, arrays, and error handling.
Practice regularly by automating your daily tasks. The more you script, the more comfortable you'll become with the syntax and the more creative solutions you'll discover for complex problems.