Bash 13: Bash Scripting Practice Tasks

Bash 13: Bash Scripting Practice Tasks

Objective: Practice writing and optimizing Bash scripts through a series of structured tasks.


Elevating Your Bash Scripting Skills

Welcome back to our series, "Pentesting - Scripting with Bash." In our previous posts, we've explored a wide range of topics from basic scripting to advanced techniques and real-world scenarios. Today, we'll provide a series of tasks to help you practice and solidify your Bash scripting skills. These tasks will guide you through specific scripting exercises, improving your skills in code readability, performance optimization, and security considerations.

Bash Scripting Practice Tasks

Task 1: Basic Script Writing

Step 1: Write a script that prints "Hello, World!" to the console.

#!/bin/bash
echo "Hello, World!"

Step 2: Modify the script to ask the user for their name and print a personalized greeting.

#!/bin/bash
read -p "Enter your name: " name
echo "Hello, $name!"

Task 2: Using Variables and Arithmetic

Step 1: Write a script that takes two numbers as input and prints their sum.

#!/bin/bash
read -p "Enter the first number: " num1
read -p "Enter the second number: " num2
sum=$((num1 + num2))
echo "The sum is: $sum"

Step 2: Modify the script to perform subtraction, multiplication, and division as well.

#!/bin/bash
read -p "Enter the first number: " num1
read -p "Enter the second number: " num2
sum=$((num1 + num2))
difference=$((num1 - num2))
product=$((num1 * num2))
if [ $num2 -ne 0 ]; then
    quotient=$((num1 / num2))
else
    quotient="undefined (division by zero)"
fi
echo "Sum: $sum"
echo "Difference: $difference"
echo "Product: $product"
echo "Quotient: $quotient"

Task 3: Conditionals and Loops

Step 1: Write a script that checks if a file exists and prints a message accordingly.

#!/bin/bash
read -p "Enter the file name: " filename
if [ -f "$filename" ]; then
    echo "File exists."
else
    echo "File does not exist."
fi

Step 2: Modify the script to repeatedly ask for a file name until the user provides a valid file.

#!/bin/bash
while true; do
    read -p "Enter the file name: " filename
    if [ -f "$filename" ]; then
        echo "File exists."
        break
    else
        echo "File does not exist. Try again."
    fi
done

Task 4: Functions and Modularization

Step 1: Write a script with a function that checks if a number is even or odd.

#!/bin/bash
check_even_odd() {
    if [ $(( $1 % 2 )) -eq 0 ]; then
        echo "$1 is even."
    else
        echo "$1 is odd."
    fi
}

read -p "Enter a number: " num
check_even_odd $num

Step 2: Modify the script to repeatedly ask for numbers and check if they are even or odd, until the user enters 'exit'.

#!/bin/bash
check_even_odd() {
    if [ $(( $1 % 2 )) -eq 0 ]; then
        echo "$1 is even."
    else
        echo "$1 is odd."
    fi
}

while true; do
    read -p "Enter a number (or type 'exit' to quit): " input
    if [ "$input" == "exit" ]; then
        break
    elif [[ "$input" =~ ^[0-9]+$ ]]; then
        check_even_odd $input
    else
        echo "Invalid input. Please enter a number."
    fi
done

Task 5: Handling User Input and Validation

Step 1: Write a script that takes a username as input and validates if it meets certain criteria (e.g., only alphanumeric characters and underscores, at least 5 characters long).

#!/bin/bash
validate_username() {
    if [[ "$1" =~ ^[a-zA-Z0-9_]{5,}$ ]]; then
        echo "Valid username."
    else
        echo "Invalid username. Must be at least 5 characters long and contain only alphanumeric characters and underscores."
    fi
}

read -p "Enter a username: " username
validate_username $username

Step 2: Modify the script to keep asking for a valid username until the user provides one that meets the criteria.

#!/bin/bash
validate_username() {
    if [[ "$1" =~ ^[a-zA-Z0-9_]{5,}$ ]]; then
        echo "Valid username."
        return 0
    else
        echo "Invalid username. Must be at least 5 characters long and contain only alphanumeric characters and underscores."
        return 1
    fi
}

while true; do
    read -p "Enter a username: " username
    validate_username $username && break
done

Task 6: Reading and Writing to Files

Step 1: Write a script that reads lines from a file and prints them to the console.

#!/bin/bash
read -p "Enter the file name: " filename
if [ -f "$filename" ]; then
    while IFS= read -r line; do
        echo "$line"
    done < "$filename"
else
    echo "File not found."
fi

Step 2: Modify the script to write user input to a file, appending each new input as a new line.

#!/bin/bash
read -p "Enter the file name to write to: " filename
while true; do
    read -p "Enter text to append (or type 'exit' to quit): " input
    if [ "$input" == "exit" ]; then
        break
    else
        echo "$input" >> "$filename"
    fi
done

Task 7: Scheduling and Automation with Cron

Step 1: Write a script that creates a backup of a specified directory and stores it in a backup location.

#!/bin/bash
read -p "Enter the directory to back up: " source_dir
read -p "Enter the backup location: " backup_dir
timestamp=$(date +"%Y%m%d_%H%M%S")
backup_file="$backup_dir/backup_$timestamp.tar.gz"

if [ -d "$source_dir" ]; then
    tar -czf "$backup_file" -C "$source_dir" .
    echo "Backup created at $backup_file"
else
    echo "Source directory not found."
fi

Step 2: Create a cron job to run the backup script every day at a specified time.

  1. Edit the crontab file:

     crontab -e
    
  2. Add the following line to schedule the backup script to run daily at 2 AM:

     0 2 * * * /path/to/backup_script.sh
    

Task 8: Network Operations

Step 1: Write a script that pings a list of servers and logs the results.

#!/bin/bash
servers=("google.com" "yahoo.com" "bing.com")
log_file="ping_results.log"

for server in "${servers[@]}"; do
    echo "Pinging $server..." | tee -a $log_file
    ping -c 4 $server | tee -a $log_file
    echo "-----------------------------" | tee -a $log_file
done

Step 2: Modify the script to read the list of servers from a file.

#!/bin/bash
read -p "Enter the file containing the list of servers: " server_file
log_file="ping_results.log"

if [ -f "$server_file" ]; then
    while IFS= read -r server; do
        echo "Pinging $server..." | tee -a $log_file
        ping -c 4 $server | tee -a $log_file
        echo "-----------------------------" | tee -a $log_file
    done < "$server_file"
else
    echo "Server file not found."
fi

Task 9: Secure Scripting Practices

Step 1: Write a script that securely handles sensitive information by reading it from a file with restricted permissions.

#!/bin/bash
read -sp "Enter the password file path: " password_file
echo
if [ -f "$password_file" ]; then
    db_password=$(<"$password_file")
    echo "Password read successfully."
    # Simulate using the password (e.g., connect to a database)
else
    echo "Password file not found."
fi

Step 2: Ensure the password file has the correct permissions.

chmod 600 /path/to/password_file

Task 10: Refactoring and Optimization

Step 1: Given the following script, refactor it to follow best practices and improve performance.

Original Script:

#!/bin/bash
for i in {1..100}; do
    echo "Number $i"
done

Refactored Script:

#!/bin/bash

# Function to print numbers
print_numbers() {
    local start=$1
    local end=$2
    for ((i=start; i<=end; i++)); do
        echo "Number $i"
    done
}

print_numbers 1 100

Conclusion

By completing these tasks, you'll gain hands-on experience with Bash scripting, focusing on best practices, performance optimization, and security considerations. These exercises will help you write clean, maintainable, and efficient scripts that are secure and less prone to errors. Happy scripting!