DEV Community

methew smith
methew smith

Posted on

scripting

File: systeminfo.sh

#!/bin/bash
# systeminfo.sh
# Purpose: Display system information including kernel, processor, OS, and editor info
# Usage: ./systeminfo.sh

echo "========================================="
echo "         SYSTEM INFORMATION REPORT       "
echo "========================================="

# Print kernel name (e.g., Linux)
echo "Kernel Name     : $(uname -s)"

# Print kernel release version (e.g., 5.15.0-91-generic)
echo "Kernel Release  : $(uname -r)"

# Print processor/hardware type (e.g., x86_64)
echo "Processor Type  : $(uname -p)"

# Print the installed operating system name and version
echo "Operating System: $(lsb_release -d | cut -f2)"

echo ""
echo "========================================="
echo "           FAVORITE EDITOR INFO          "
echo "========================================="

# Define favorite editor
EDITOR_NAME="nano"

# Display the name of the favorite editor
echo "Favorite Editor : $EDITOR_NAME"

# Show where the editor binary is located using 'which'
echo "Editor Location : $(which $EDITOR_NAME)"

# Show where the editor documentation/manual is located using 'whereis'
echo "Documentation   : $(whereis $EDITOR_NAME)"

echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x systeminfo.sh
./systeminfo.sh
Enter fullscreen mode Exit fullscreen mode

Expected Output:

=========================================
         SYSTEM INFORMATION REPORT
=========================================
Kernel Name     : Linux
Kernel Release  : 5.15.0-91-generic
Processor Type  : x86_64
Operating System: Ubuntu 22.04.3 LTS
=========================================
           FAVORITE EDITOR INFO
=========================================
Favorite Editor : nano
Editor Location : /usr/bin/nano
Documentation   : nano: /usr/bin/nano /usr/share/man/man1/nano.1.gz
=========================================
Enter fullscreen mode Exit fullscreen mode

User and Group Management
File: usergroup.sh

#!/bin/bash
# usergroup.sh
# Purpose: Create a user, a group, and add the user to the group
# Usage: ./usergroup.sh

echo "========================================="
echo "       USER AND GROUP MANAGEMENT         "
echo "========================================="

# Step 1: Create a new user named 'devopsuser'
# -m flag creates the home directory automatically
# -s sets the default shell to bash
if id "devopsuser" &>/dev/null; then
    # Check if user already exists to avoid errors
    echo "[INFO] User 'devopsuser' already exists. Skipping creation."
else
    sudo useradd -m -s /bin/bash devopsuser
    echo "[SUCCESS] User 'devopsuser' created successfully."
fi

# Step 2: Create a new group named 'devopsgroup'
if getent group devopsgroup &>/dev/null; then
    # Check if group already exists to avoid errors
    echo "[INFO] Group 'devopsgroup' already exists. Skipping creation."
else
    sudo groupadd devopsgroup
    echo "[SUCCESS] Group 'devopsgroup' created successfully."
fi

# Step 3: Add 'devopsuser' to 'devopsgroup'
# usermod -aG appends the user to the group without removing from other groups
sudo usermod -aG devopsgroup devopsuser
echo "[SUCCESS] User 'devopsuser' added to group 'devopsgroup'."

# Display verification — show the groups the user belongs to
echo ""
echo "--- Verification ---"
echo "Groups for devopsuser:"
groups devopsuser

echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x usergroup.sh
./usergroup.sh
Enter fullscreen mode Exit fullscreen mode

Expected Output:

=========================================
       USER AND GROUP MANAGEMENT
=========================================
[SUCCESS] User 'devopsuser' created successfully.
[SUCCESS] Group 'devopsgroup' created successfully.
[SUCCESS] User 'devopsuser' added to group 'devopsgroup'.

--- Verification ---
Groups for devopsuser: devopsuser devopsgroup
=========================================
Enter fullscreen mode Exit fullscreen mode

Question 3: SSH Configuration

File: sshconfig.sh

#!/bin/bash
# sshconfig.sh
# Purpose: Generate SSH key pair, configure passwordless login, and run non-interactive SSH tasks
# Usage: ./sshconfig.sh

echo "========================================="
echo "          SSH CONFIGURATION SCRIPT       "
echo "========================================="

# Define the target user and their home directory
TARGET_USER="devopsuser"
USER_HOME="/home/$TARGET_USER"
SSH_DIR="$USER_HOME/.ssh"

# -----------------------------------------------
# Step 1: Generate SSH key pair for devopsuser
# -----------------------------------------------
echo "[STEP 1] Generating SSH key pair for $TARGET_USER..."

# Create .ssh directory inside devopsuser's home if it doesn't exist
sudo mkdir -p $SSH_DIR

# Generate RSA key pair with no passphrase (-N "")
# -t rsa   → use RSA algorithm
# -b 2048  → 2048-bit key strength
# -f       → specify the output file path
# -N ""    → no passphrase (for automation)
sudo ssh-keygen -t rsa -b 2048 -f $SSH_DIR/id_rsa -N "" -C "$TARGET_USER@localhost"

# Copy public key to authorized_keys so the user can login with the private key
sudo cat $SSH_DIR/id_rsa.pub | sudo tee $SSH_DIR/authorized_keys > /dev/null

# Set correct permissions — SSH is strict about permissions
# 700 = only owner can access the .ssh folder
# 600 = only owner can read/write the key files
sudo chmod 700 $SSH_DIR
sudo chmod 600 $SSH_DIR/authorized_keys
sudo chmod 600 $SSH_DIR/id_rsa
sudo chmod 644 $SSH_DIR/id_rsa.pub

# Make devopsuser own all these files
sudo chown -R $TARGET_USER:$TARGET_USER $SSH_DIR

echo "[SUCCESS] SSH key pair generated and saved to $SSH_DIR"

# -----------------------------------------------
# Step 2: Disable password authentication in SSH config
# -----------------------------------------------
echo "[STEP 2] Disabling password authentication in /etc/ssh/sshd_config..."

# Edit SSH server config to disable password-based login
# This forces key-based authentication only
sudo sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# Also ensure PubkeyAuthentication is enabled
sudo sed -i 's/^#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config

# Restart SSH service to apply changes
sudo systemctl restart ssh
echo "[SUCCESS] Password authentication disabled. Key-based auth enabled."

# -----------------------------------------------
# Step 3: Set up SSH shortcut in ~/.ssh/config
# -----------------------------------------------
echo "[STEP 3] Setting up SSH config shortcut..."

# Create SSH client config file so user doesn't need to type full username and IP
# This allows: ssh devopsserver  instead of: ssh devopsuser@127.0.0.1
sudo tee $SSH_DIR/config << EOF
# SSH shortcut configuration for devopsuser
Host devopsserver
    HostName 127.0.0.1
    User $TARGET_USER
    Port 22
    IdentityFile $SSH_DIR/id_rsa
EOF

# Fix permissions on config file
sudo chmod 600 $SSH_DIR/config
sudo chown $TARGET_USER:$TARGET_USER $SSH_DIR/config

echo "[SUCCESS] SSH config shortcut created. Use: ssh devopsserver"

# -----------------------------------------------
# Step 3a: SSH in non-interactive mode and run tasks
# -----------------------------------------------
echo "[STEP 3a] Running tasks via non-interactive SSH..."

# Task b: Create a test directory inside home directory
# -o StrictHostKeyChecking=no → skip host fingerprint prompt (for automation)
sudo -u $TARGET_USER ssh -o StrictHostKeyChecking=no \
    -i $SSH_DIR/id_rsa \
    $TARGET_USER@127.0.0.1 \
    "mkdir -p ~/testdir"
echo "[SUCCESS] Test directory 'testdir' created inside $USER_HOME"

# Task c: Create file and write the required text into it
sudo -u $TARGET_USER ssh -o StrictHostKeyChecking=no \
    -i $SSH_DIR/id_rsa \
    $TARGET_USER@127.0.0.1 \
    "echo 'I am doing the task3.' > ~/testdir/filecreatedinnoninteractivemode.txt"
echo "[SUCCESS] File 'filecreatedinnoninteractivemode.txt' created with required content."

# Verify the file contents
echo ""
echo "--- Verification: File Contents ---"
sudo cat $USER_HOME/testdir/filecreatedinnoninteractivemode.txt

echo "========================================="
echo "     SSH CONFIGURATION COMPLETE          "
echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x sshconfig.sh
sudo ./sshconfig.sh
Enter fullscreen mode Exit fullscreen mode

Question 4: File and Directory Manipulation

File: filedir.sh

#!/bin/bash
# filedir.sh
# Purpose: Create directory, file, write content, and set correct permissions
# Usage: ./filedir.sh

echo "========================================="
echo "     FILE AND DIRECTORY MANIPULATION     "
echo "========================================="

# Step 1: Create the directory /devopsdir
# -p flag prevents error if directory already exists
sudo mkdir -p /devopsdir
echo "[SUCCESS] Directory '/devopsdir' created."

# Step 2: Create file inside /devopsdir and write the required text
# Using tee with sudo so we can write to the protected /devopsdir
echo "AoA, Hello DevOps!" | sudo tee /devopsdir/devopsfile.txt > /dev/null
echo "[SUCCESS] File 'devopsfile.txt' created with content: 'AoA, Hello DevOps!'"

# Step 3: Set permissions for devopsuser and other users
# We need to set:
#   - devopsuser → rw- on the file (read + write) → 6
#   - devopsuser → rwx on the directory (read + write + execute) → 7
#   - Others     → r-- on the file (read only) → 4
#   - Others     → r-- on the directory (read only) → 4

# Change owner of /devopsdir and its contents to devopsuser
sudo chown -R devopsuser:devopsuser /devopsdir

# Set permissions on the directory: rwxr--r-- (744)
# devopsuser: rwx (7), group: r-- (4), others: r-- (4)
sudo chmod 744 /devopsdir

# Set permissions on the file: rw-r--r-- (644)
# devopsuser: rw- (6), group: r-- (4), others: r-- (4)
sudo chmod 644 /devopsdir/devopsfile.txt

echo "[SUCCESS] Permissions set:"
echo "  /devopsdir       → 744 (devopsuser: rwx, others: r--)"
echo "  devopsfile.txt   → 644 (devopsuser: rw-, others: r--)"

# Verify — display the final permissions
echo ""
echo "--- Verification ---"
ls -ld /devopsdir
ls -l /devopsdir/devopsfile.txt
echo ""
echo "--- File Content ---"
cat /devopsdir/devopsfile.txt

echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x filedir.sh
sudo ./filedir.sh
Enter fullscreen mode Exit fullscreen mode

Expected Output:

=========================================
     FILE AND DIRECTORY MANIPULATION
=========================================
[SUCCESS] Directory '/devopsdir' created.
[SUCCESS] File 'devopsfile.txt' created with content: 'AoA, Hello DevOps!'
[SUCCESS] Permissions set:
  /devopsdir       → 744 (devopsuser: rwx, others: r--)
  devopsfile.txt   → 644 (devopsuser: rw-, others: r--)

--- Verification ---
drwxr--r-- 2 devopsuser devopsuser 4096 Mar 15 12:00 /devopsdir
-rw-r--r-- 1 devopsuser devopsuser   19 Mar 15 12:00 /devopsdir/devopsfile.txt

--- File Content ---
AoA, Hello DevOps!
=========================================
Enter fullscreen mode Exit fullscreen mode

Question 5: Backup Script

File: backup.sh

#!/bin/bash
# backup.sh
# Purpose: Compress /devopsdir into a timestamped tarball and save to devopsuser's backup folder
# Usage: ./backup.sh
# Bonus: Also sets up a cron job to run this backup every 10 minutes

echo "========================================="
echo "            BACKUP SCRIPT                "
echo "========================================="

# Define variables
SOURCE_DIR="/devopsdir"                            # Directory to back up
BACKUP_DIR="/home/devopsuser/backup"               # Where to save backups
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")            # Unique timestamp: e.g., 2026-03-15_14-30-00
BACKUP_FILE="$BACKUP_DIR/devopsdir_backup_$TIMESTAMP.tar.gz"  # Full backup filename

# Step 1: Create backup directory if it doesn't exist
mkdir -p $BACKUP_DIR
echo "[INFO] Backup directory: $BACKUP_DIR"

# Step 2: Check if source directory exists before backing up
if [ ! -d "$SOURCE_DIR" ]; then
    echo "[ERROR] Source directory '$SOURCE_DIR' does not exist. Exiting."
    exit 1
fi

# Step 3: Create compressed tarball of /devopsdir
# -c → create archive
# -z → compress with gzip
# -f → specify filename
# -v → verbose (show files being added)
tar -czf $BACKUP_FILE $SOURCE_DIR 2>/dev/null

# Step 4: Check if backup was created successfully using exit code $?
if [ $? -eq 0 ]; then
    echo "[SUCCESS] Backup created: $BACKUP_FILE"
    echo "[INFO] Backup size: $(du -sh $BACKUP_FILE | cut -f1)"
else
    echo "[ERROR] Backup failed!"
    exit 1
fi

# -----------------------------------------------
# BONUS: Set up cron job to run backup every 10 minutes
# -----------------------------------------------
echo ""
echo "[BONUS] Setting up cron job for automatic backup every 10 minutes..."

# Get the absolute path of this script
SCRIPT_PATH=$(realpath $0)

# Add cron job for devopsuser — run backup.sh every 10 minutes
# crontab -l lists existing cron jobs
# We check first to avoid duplicate entries
CRON_JOB="*/10 * * * * $SCRIPT_PATH"

# Check if cron job already exists
(crontab -l 2>/dev/null | grep -q "$SCRIPT_PATH") && \
    echo "[INFO] Cron job already exists. Skipping." || \
    (crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -

echo "[SUCCESS] Cron job set: backup runs every 10 minutes."
echo ""
echo "--- Current Cron Jobs ---"
crontab -l

echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x backup.sh
./backup.sh
Enter fullscreen mode Exit fullscreen mode

Expected Output:

=========================================
            BACKUP SCRIPT
=========================================
[INFO] Backup directory: /home/devopsuser/backup
[SUCCESS] Backup created: /home/devopsuser/backup/devopsdir_backup_2026-03-15_14-30-00.tar.gz
[INFO] Backup size: 4.0K

[BONUS] Setting up cron job for automatic backup every 10 minutes...
[SUCCESS] Cron job set: backup runs every 10 minutes.

--- Current Cron Jobs ---
*/10 * * * * /path/to/backup.sh
=========================================
Enter fullscreen mode Exit fullscreen mode

Question 6: System Health Report (40 Marks)

File: system_health.sh

#!/bin/bash
# system_health.sh
# Purpose: Collect system health info and generate an HTML report, then host it with nginx
# Usage: ./system_health.sh

OUTPUT_FILE="/var/www/html/system_health.html"

echo "========================================="
echo "        SYSTEM HEALTH REPORT             "
echo "========================================="

# -----------------------------------------------
# Collect: Current Date and Time
# -----------------------------------------------
CURRENT_DATE=$(date "+%A, %B %d %Y %I:%M %p")

# -----------------------------------------------
# Collect: Memory Information using free + awk
# -----------------------------------------------

# Total memory in MB
TOTAL_MEM=$(free -m | awk '/^Mem:/ {print $2}')

# Used memory in MB
USED_MEM=$(free -m | awk '/^Mem:/ {print $3}')

# Available memory in MB
AVAIL_MEM=$(free -m | awk '/^Mem:/ {print $7}')

# Used memory as percentage
USED_MEM_PCT=$(free | awk '/^Mem:/ {printf("%.1f", $3/$2 * 100)}')

# Available memory as percentage
AVAIL_MEM_PCT=$(free | awk '/^Mem:/ {printf("%.1f", $7/$2 * 100)}')

# Total swap memory in MB
TOTAL_SWAP=$(free -m | awk '/^Swap:/ {print $2}')

# Used swap in MB
USED_SWAP=$(free -m | awk '/^Swap:/ {print $3}')

# Used swap as percentage (avoid divide by zero if no swap)
USED_SWAP_PCT=$(free | awk '/^Swap:/ { if($2 > 0) printf("%.1f", $3/$2 * 100); else print "0.0" }')

# Available swap as percentage
AVAIL_SWAP_PCT=$(free | awk '/^Swap:/ { if($2 > 0) printf("%.1f", ($2-$3)/$2 * 100); else print "0.0" }')

# -----------------------------------------------
# Collect: Disk Information using df + awk
# -----------------------------------------------

# Total disk space (root partition)
TOTAL_DISK=$(df -h / | awk 'NR==2 {print $2}')

# Used disk space
USED_DISK=$(df -h / | awk 'NR==2 {print $3}')

# Available disk space
AVAIL_DISK=$(df -h / | awk 'NR==2 {print $4}')

# List partitioned disks — exclude tmpfs using awk regex
# ^ means starts with, ! negates the match — exclude lines starting with tmpfs
DISK_LIST=$(df -h | awk '!/^tmpfs/ && !/^Filesystem/ {print $1, $3, $4}')

# -----------------------------------------------
# Write everything into HTML using heredoc
# -----------------------------------------------
echo "[INFO] Writing HTML report..."

sudo tee $OUTPUT_FILE << EOF
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>System Health Report</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #1a1a2e;
            color: #e0e0e0;
            margin: 0;
            padding: 20px;
        }
        h1 {
            color: #00d4ff;
            text-align: center;
            border-bottom: 2px solid #00d4ff;
            padding-bottom: 10px;
        }
        h2 {
            color: #00d4ff;
            margin-top: 30px;
        }
        .section {
            background-color: #16213e;
            border-radius: 8px;
            padding: 20px;
            margin: 20px 0;
            border-left: 4px solid #00d4ff;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
        }
        th {
            background-color: #0f3460;
            color: #00d4ff;
            padding: 10px;
            text-align: left;
        }
        td {
            padding: 8px 10px;
            border-bottom: 1px solid #0f3460;
        }
        tr:hover {
            background-color: #0f3460;
        }
        .date {
            text-align: center;
            font-size: 1.1em;
            color: #aaa;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>

<h1>🖥️ System Health Report</h1>
<p class="date">Generated on: $CURRENT_DATE</p>

<!-- Memory Section -->
<div class="section">
    <h2>💾 Memory Usage</h2>
    <table>
        <tr>
            <th>Type</th>
            <th>Total</th>
            <th>Used</th>
            <th>Used %</th>
            <th>Available %</th>
        </tr>
        <tr>
            <td>RAM</td>
            <td>${TOTAL_MEM} MB</td>
            <td>${USED_MEM} MB</td>
            <td>${USED_MEM_PCT}%</td>
            <td>${AVAIL_MEM_PCT}%</td>
        </tr>
        <tr>
            <td>Swap</td>
            <td>${TOTAL_SWAP} MB</td>
            <td>${USED_SWAP} MB</td>
            <td>${USED_SWAP_PCT}%</td>
            <td>${AVAIL_SWAP_PCT}%</td>
        </tr>
    </table>
</div>

<!-- Disk Section -->
<div class="section">
    <h2>💿 Disk Usage</h2>
    <table>
        <tr>
            <th>Total Space</th>
            <th>Used</th>
            <th>Available</th>
        </tr>
        <tr>
            <td>$TOTAL_DISK</td>
            <td>$USED_DISK</td>
            <td>$AVAIL_DISK</td>
        </tr>
    </table>

    <h2>📂 Partitioned Disks (excluding tmpfs)</h2>
    <table>
        <tr>
            <th>Disk Name</th>
            <th>Used</th>
            <th>Available</th>
        </tr>
$(df -h | awk '!/^tmpfs/ && !/^Filesystem/ {print "<tr><td>"$1"</td><td>"$3"</td><td>"$4"</td></tr>"}')
    </table>
</div>

</body>
</html>
EOF

# -----------------------------------------------
# Host the HTML file using Nginx
# -----------------------------------------------
echo "[INFO] Setting up Nginx to host the report..."

# Install nginx if not already installed
if ! command -v nginx &>/dev/null; then
    sudo apt update -y && sudo apt install nginx -y
fi

# Copy report to nginx web root as index.html
sudo cp $OUTPUT_FILE /var/www/html/index.html

# Start and enable nginx
sudo systemctl start nginx
sudo systemctl enable nginx

# Check if nginx started successfully using exit code
if [ $? -eq 0 ]; then
    echo "[SUCCESS] System health report is live at: http://localhost"
else
    echo "[ERROR] Nginx failed to start."
    exit 1
fi

echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x system_health.sh
sudo ./system_health.sh
Enter fullscreen mode Exit fullscreen mode

Question 7: LAMP Stack Automation

File: bsc-configuring-lamp-environment.sh

#!/bin/bash
# bsc-configuring-lamp-environment.sh
# Purpose: Automate installation and removal of full LAMP stack (Linux, Apache/Nginx, MySQL, PHP)
# Usage:
#   ./bsc-configuring-lamp-environment.sh -i           → install with default Apache
#   ./bsc-configuring-lamp-environment.sh -i -ws Apache → install with Apache
#   ./bsc-configuring-lamp-environment.sh -i -ws Nginx  → install with Nginx
#   ./bsc-configuring-lamp-environment.sh -d            → delete all LAMP services

# -----------------------------------------------
# LOG FILE SETUP
# -----------------------------------------------
# Create a log file with your registration number in the name
REG_NUMBER="YOUR_REG_NUMBER"      # ← Replace with your actual reg number
LOG_FILE="lamp-setup-${REG_NUMBER}.log"

# Function to write timestamped log entries
log() {
    # Each log entry gets a timestamp like: [2026-03-15 14:30:21] message
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# -----------------------------------------------
# PARSE COMMAND LINE ARGUMENTS
# -----------------------------------------------
ACTION=""          # Will be 'install' or 'delete'
WEB_SERVER="Apache" # Default web server is Apache

# Loop through all arguments using getopts
while getopts ":idw:s:" opt; do
    case $opt in
        i) ACTION="install" ;;       # -i flag → install
        d) ACTION="delete" ;;        # -d flag → delete
        w) ;;                        # partial -ws handling
        s) WEB_SERVER="$OPTARG" ;;   # capture Apache or Nginx value
        ?) echo "[ERROR] Unknown option: -$OPTARG"; exit 1 ;;
    esac
done

# Handle -ws Apache or -ws Nginx as combined argument
for arg in "$@"; do
    if [[ "$arg" == "Apache" || "$arg" == "Nginx" ]]; then
        WEB_SERVER="$arg"
    fi
done

# Validate — must provide either -i or -d
if [ -z "$ACTION" ]; then
    echo "Usage: $0 -i [-ws Apache|Nginx]   → install LAMP"
    echo "       $0 -d                       → delete LAMP"
    exit 1
fi

# -----------------------------------------------
# FUNCTION: Install Web Server (Apache or Nginx)
# -----------------------------------------------
install_webserver() {
    log "Starting Web Server installation: $WEB_SERVER"

    if [ "$WEB_SERVER" == "Apache" ]; then
        # Check if Apache is already installed
        if dpkg -l | grep -q apache2; then
            echo "[INFO] Apache web server is already installed."
            read -p "Do you want to remove it and reinstall? (Y/n): " CONFIRM
            if [[ "$CONFIRM" == "Y" || "$CONFIRM" == "y" ]]; then
                log "Removing existing Apache installation..."
                sudo apt remove --purge apache2 -y
                log "Apache removed."
            else
                log "Skipping Apache reinstall. Continuing..."
                return
            fi
        fi
        # Install Apache without user interaction
        log "Installing Apache Web Server..."
        sudo apt update -y
        sudo DEBIAN_FRONTEND=noninteractive apt install apache2 -y
        sudo systemctl start apache2
        sudo systemctl enable apache2
        log "Apache Web Server installed and started successfully."
        echo "[SUCCESS] Apache installed. Visit http://localhost"

    elif [ "$WEB_SERVER" == "Nginx" ]; then
        # Check if Nginx is already installed
        if dpkg -l | grep -q nginx; then
            echo "[INFO] Nginx web server is already installed."
            read -p "Do you want to remove it and reinstall? (Y/n): " CONFIRM
            if [[ "$CONFIRM" == "Y" || "$CONFIRM" == "y" ]]; then
                log "Removing existing Nginx installation..."
                sudo apt remove --purge nginx -y
                log "Nginx removed."
            else
                log "Skipping Nginx reinstall. Continuing..."
                return
            fi
        fi
        # Install Nginx without user interaction
        log "Installing Nginx Web Server..."
        sudo apt update -y
        sudo DEBIAN_FRONTEND=noninteractive apt install nginx -y
        sudo systemctl start nginx
        sudo systemctl enable nginx
        log "Nginx Web Server installed and started successfully."
        echo "[SUCCESS] Nginx installed. Visit http://localhost"
    else
        log "[ERROR] Invalid web server: $WEB_SERVER. Choose Apache or Nginx."
        exit 1
    fi
}

# -----------------------------------------------
# FUNCTION: Install PHP and required modules
# -----------------------------------------------
install_php() {
    log "Starting PHP installation..."

    # Check if PHP is already installed
    if command -v php &>/dev/null; then
        PHP_VERSION=$(php -r "echo PHP_VERSION;")
        echo "[INFO] PHP is already installed. Version: $PHP_VERSION"
        log "PHP already installed. Version: $PHP_VERSION"
        return
    fi

    # Install PHP with common modules needed for a basic PHP application
    # php-mysql     → MySQL support
    # php-curl      → HTTP requests
    # php-xml       → XML processing
    # php-mbstring  → Multibyte string handling
    # php-zip       → ZIP file support
    log "Installing PHP and required modules..."
    sudo DEBIAN_FRONTEND=noninteractive apt install php libapache2-mod-php \
        php-mysql php-curl php-xml php-mbstring php-zip php-gd -y

    log "PHP installed successfully. Version: $(php -r 'echo PHP_VERSION;')"
    echo "[SUCCESS] PHP installed. Version: $(php --version | head -1)"
}

# -----------------------------------------------
# FUNCTION: Install MySQL and generate root password
# -----------------------------------------------
install_mysql() {
    log "Starting MySQL installation..."

    # Check if MySQL is already installed
    if command -v mysql &>/dev/null; then
        echo "[INFO] MySQL is already installed."
        log "MySQL already installed. Skipping."
        return
    fi

    # Generate a random root password (16 characters)
    MYSQL_ROOT_PASS=$(openssl rand -base64 16)

    log "Installing MySQL Server..."
    # Set root password non-interactively using debconf
    sudo debconf-set-selections <<< "mysql-server mysql-server/root_password password $MYSQL_ROOT_PASS"
    sudo debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASS"

    sudo DEBIAN_FRONTEND=noninteractive apt install mysql-server -y

    # Start and enable MySQL
    sudo systemctl start mysql
    sudo systemctl enable mysql

    log "MySQL installed successfully."

    # Display the generated password to the user
    echo ""
    echo "========================================"
    echo "  ⚠️  IMPORTANT: SAVE THIS PASSWORD!"
    echo "  MySQL Root Password: $MYSQL_ROOT_PASS"
    echo "========================================"
    echo ""
    log "MySQL root password generated and displayed to user."
}

# -----------------------------------------------
# FUNCTION: Delete all LAMP services
# -----------------------------------------------
delete_lamp() {
    log "LAMP stack deletion requested."

    # Show serious warning before deleting
    echo ""
    echo "=========================================================="
    echo "  ⚠️  WARNING: You are about to DELETE the LAMP stack!"
    echo "  This will remove Apache/Nginx, PHP, and MySQL."
    echo "  ALL DATA WILL BE LOST. Please take a backup first!"
    echo "=========================================================="
    echo ""

    # Ask user to confirm — double confirmation for safety
    read -p "Have you taken a backup? Are you sure you want to continue? (Y/n): " CONFIRM

    if [[ "$CONFIRM" != "Y" && "$CONFIRM" != "y" ]]; then
        echo "[INFO] Deletion cancelled. No changes made."
        log "Deletion cancelled by user."
        exit 0
    fi

    log "User confirmed deletion. Proceeding to remove LAMP stack..."

    # Remove Apache if installed
    if dpkg -l | grep -q apache2; then
        log "Removing Apache..."
        sudo apt remove --purge apache2 apache2-utils -y
        sudo apt autoremove -y
        log "Apache removed."
        echo "[SUCCESS] Apache removed."
    fi

    # Remove Nginx if installed
    if dpkg -l | grep -q nginx; then
        log "Removing Nginx..."
        sudo apt remove --purge nginx nginx-common -y
        sudo apt autoremove -y
        log "Nginx removed."
        echo "[SUCCESS] Nginx removed."
    fi

    # Remove PHP and all modules
    if command -v php &>/dev/null; then
        log "Removing PHP..."
        sudo apt remove --purge php* -y
        sudo apt autoremove -y
        log "PHP removed."
        echo "[SUCCESS] PHP removed."
    fi

    # Remove MySQL
    if command -v mysql &>/dev/null; then
        log "Removing MySQL..."
        sudo apt remove --purge mysql-server mysql-client mysql-common -y
        sudo apt autoremove -y
        sudo rm -rf /var/lib/mysql /etc/mysql
        log "MySQL removed."
        echo "[SUCCESS] MySQL removed."
    fi

    log "LAMP stack deletion complete."
    echo ""
    echo "[SUCCESS] All LAMP services have been removed."
}

# -----------------------------------------------
# MAIN: Execute based on action flag
# -----------------------------------------------
log "========= Script started ========="
log "Action: $ACTION | Web Server: $WEB_SERVER"

if [ "$ACTION" == "install" ]; then
    echo "[INFO] Starting LAMP stack installation..."
    install_webserver
    install_php
    install_mysql
    log "========= LAMP installation complete ========="
    echo ""
    echo "[SUCCESS] LAMP stack fully installed!"
    echo "  Web Server : $WEB_SERVER → http://localhost"
    echo "  PHP        : $(php -r 'echo PHP_VERSION;')"
    echo "  MySQL      : Running"
    echo "  Log file   : $LOG_FILE"

elif [ "$ACTION" == "delete" ]; then
    delete_lamp
    log "========= Script ended ========="
fi
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x bsc-configuring-lamp-environment.sh

# Install with Apache (default)
sudo ./bsc-configuring-lamp-environment.sh -i

# Install with Nginx
sudo ./bsc-configuring-lamp-environment.sh -i -ws Nginx

# Delete everything
sudo ./bsc-configuring-lamp-environment.sh -d
Enter fullscreen mode Exit fullscreen mode

Question 8: Submit Script (10 Marks)

File: submit.sh

#!/bin/bash
# submit.sh
# Purpose: Bundle all bash scripts from this assignment into a compressed tarball for submission
# Usage: ./submit.sh

echo "========================================="
echo "         ASSIGNMENT SUBMISSION SCRIPT    "
echo "========================================="

# Define your registration number — change this to your actual reg number
REG_NUMBER="YOUR_REG_NUMBER"

# Define the output tarball name using reg number
TARBALL_NAME="${REG_NUMBER}.tar.gz"

# -----------------------------------------------
# Step 1: Find all bash scripts in current directory
# -----------------------------------------------
# Use *.sh pattern to match ALL bash scripts automatically
# This handles any number of scripts without naming them manually
echo "[INFO] Finding all bash scripts..."
SCRIPTS=$(ls *.sh 2>/dev/null)

# Check if any scripts exist
if [ -z "$SCRIPTS" ]; then
    echo "[ERROR] No .sh files found in current directory!"
    exit 1
fi

echo "[INFO] Scripts found:"
for script in $SCRIPTS; do
    echo "  - $script"
done

# -----------------------------------------------
# Step 2: Create compressed tarball of all scripts
# -----------------------------------------------
# -c → create
# -z → compress with gzip
# -v → verbose (show files being added)
# -f → output filename
# *.sh → pattern matches all shell scripts (no need to name each one!)
echo ""
echo "[INFO] Creating tarball: $TARBALL_NAME"
tar -czvf $TARBALL_NAME *.sh

# Step 3: Check if tarball was created successfully
if [ $? -eq 0 ]; then
    echo ""
    echo "[SUCCESS] Tarball created: $TARBALL_NAME"
    echo "[INFO] Size: $(du -sh $TARBALL_NAME | cut -f1)"
    echo "[INFO] Contents:"
    # List what's inside the tarball to verify
    tar -tzvf $TARBALL_NAME
else
    echo "[ERROR] Failed to create tarball!"
    exit 1
fi

# -----------------------------------------------
# Step 3: Reminder to upload
# -----------------------------------------------
echo ""
echo "========================================="
echo "  ✅ Done! Now upload '$TARBALL_NAME'"
echo "     to Microsoft Teams for submission."
echo "========================================="
Enter fullscreen mode Exit fullscreen mode

Make executable and run:

chmod +x submit.sh
./submit.sh
Enter fullscreen mode Exit fullscreen mode

Expected Output:

=========================================
         ASSIGNMENT SUBMISSION SCRIPT
=========================================
[INFO] Finding all bash scripts...
[INFO] Scripts found:
  - systeminfo.sh
  - usergroup.sh
  - sshconfig.sh
  - filedir.sh
  - backup.sh
  - system_health.sh
  - bsc-configuring-lamp-environment.sh
  - submit.sh

[INFO] Creating tarball: YOUR_REG_NUMBER.tar.gz
systeminfo.sh
usergroup.sh
...

[SUCCESS] Tarball created: .tar.gz
[INFO] Size: 12K

=========================================
Enter fullscreen mode Exit fullscreen mode

Make all scripts executable at once

chmod +x *.sh

Run in order:

sudo ./systeminfo.sh
sudo ./usergroup.sh
sudo ./sshconfig.sh
sudo ./filedir.sh
./backup.sh
sudo ./system_health.sh
sudo ./bsc-configuring-lamp-environment.sh -i -ws Apache
./submit.sh


---

## 🔑 Key Commands Used — Quick Reference

Enter fullscreen mode Exit fullscreen mode


bash
uname -s # kernel name
uname -r # kernel release
uname -p # processor type
lsb_release -d # OS name
which # location of command
whereis # location + docs of command

useradd -m -s /bin/bash username # create user
groupadd groupname # create group
usermod -aG groupname username # add user to group

ssh-keygen -t rsa -b 2048 # generate RSA key pair
chmod 700 ~/.ssh # fix ssh dir permissions
chmod 600 ~/.ssh/authorized_keys # fix key file permissions

tar -czf backup.tar.gz /folder # create compressed backup
tar -tzvf backup.tar.gz # list contents of tarball
crontab -e # edit cron jobs

free -m # memory in MB
df -h # disk usage human readable
awk '/^Mem:/ {print $3/$2 * 100}' # calculate memory percent




---
Enter fullscreen mode Exit fullscreen mode

Top comments (0)