Bash Scripting Basics - Automate Your Linux Tasks

Comprehensive guide covering essential concepts, practical examples, and best practices. Learn with step-by-step tutorials and real-world applications.

Back to Articles

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!"
Output: Hello, World!
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

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.