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_count
instead 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.