Skip to main content

Command Palette

Search for a command to run...

How to Automate System Updates Using a Custom Bash Script

Published
4 min readView as Markdown
How to Automate System Updates Using a Custom Bash Script

This blog post introduces a Bash script designed to simplify Linux system updates across various distributions. With this script, you can:

  • Perform system updates with a single command.

  • Schedule updates using cron jobs for convenience.

  • Log every update for better tracking and troubleshooting.


Prerequisites

Before using this script, ensure you have:

  • Root/sudo access on your Linux system.

  • Basic knowledge of Linux commands.

  • Sufficient disk space for updates.

  • A stable internet connection.


The Script

#!/bin/bash

RELEASE_FILE="/etc/os-release"
LOG_DIR="/var/log/system_updates"
DATE=$(date '+%Y-%m-%d_%H-%M-%S')
LOG_FILE="$LOG_DIR/system_update_$DATE.log"
LOCK_FILE="/tmp/system_update.lock"
MAX_RETRIES=3
RETRY_DELAY=5

cleanup() {
    rm -f "$LOCK_FILE"
    log_message "------------------Script execution completed"
}

trap cleanup EXIT

log_message() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "$timestamp - $message" | sudo tee -a "$LOG_FILE"
}

check_system_resources() {
    local min_space=1000000
    local available_space=$(df /usr -k | awk 'NR==2 {print $4}')

    if [ "$available_space" -lt "$min_space" ]; then
        log_message "!!!!! ERROR: Insufficient disk space. Required: 1GB, Available: $((available_space / 1024))MB !!!!!"
        exit 1
    fi
}

create_lock() {
    if [ -f "$LOCK_FILE" ]; then
        local pid=$(cat "$LOCK_FILE")
        if kill -0 "$pid" 2>/dev/null; then
            log_message "*****Another update process is running. Exiting"
            exit 1
        fi
    fi
    echo $$ > "$LOCK_FILE"
}

create_log_directory() {
    if [ ! -d "$LOG_DIR" ]; then
        log_message "Creating log directory..."
        if sudo mkdir -p "$LOG_DIR"; then
            sudo chmod 750 "$LOG_DIR"
            log_message "Log directory created at $LOG_DIR"
        else
            log_message "!!!! ERROR: Failed to create log directory !!!!"
            exit 1
        fi
    fi
}

check_internet() {
    local retry=0
    while [ $retry -lt $MAX_RETRIES ]; do
        if ping -c 1 8.8.8.8 >/dev/null 2>&1; then
            return 0
        fi
        retry=$((retry + 1))
        log_message "Waiting for internet connection (attempt $retry/$MAX_RETRIES)"
        sleep $RETRY_DELAY
    done
    log_message "!!!!! ERROR: No internet connection !!!!!"
    return 1
}

update_arch() {
    log_message "----------Updating Arch Linux------------"

    if ! sudo pacman -Sy --noconfirm 2>&1 | sudo tee -a "$LOG_FILE"; then
        log_message "ERROR: Failed to sync package databases"
        return 1
    fi

    if sudo pacman -Su --noconfirm 2>&1 | sudo tee -a "$LOG_FILE"; then
        log_message "--------------Arch Linux system updated successfully"
        sudo paccache -r
    else
        log_message "!!!!! ERROR: Failed to update Arch Linux system !!!!!"
        return 1
    fi
}

update_apt() {
    log_message "--------------Updating APT-based system-------------"

    export DEBIAN_FRONTEND=noninteractive

    local retry=0
    while [ $retry -lt $MAX_RETRIES ]; do
        if sudo apt-get update -y 2>&1 | sudo tee -a "$LOG_FILE" && \
           sudo apt-get upgrade -y 2>&1 | sudo tee -a "$LOG_FILE" && \
           sudo apt-get dist-upgrade -y 2>&1 | sudo tee -a "$LOG_FILE"; then
            log_message "---------------APT system updated successfully"
            sudo apt-get autoremove -y
            sudo apt-get clean
            return 0
        fi
        retry=$((retry + 1))
        log_message "Update attempt $retry failed. Retrying in $RETRY_DELAY seconds..."
        sleep $RETRY_DELAY
    done
    log_message "!!!!! ERROR: Failed to update APT system after $MAX_RETRIES attempts !!!!!"
    return 1
}

update_redhat() {
    log_message "--------------Updating RedHat-based system---------------"

    local retry=0
    while [ $retry -lt $MAX_RETRIES ]; do
        if sudo dnf update -y 2>&1 | sudo tee -a "$LOG_FILE" && \
           sudo dnf upgrade -y 2>&1 | sudo tee -a "$LOG_FILE"; then
            log_message "---------------RedHat system updated successfully"
            sudo dnf clean all
            return 0
        fi
        retry=$((retry + 1))
        log_message "Update attempt $retry failed. Retrying in $RETRY_DELAY seconds..."
        sleep $RETRY_DELAY
    done
    log_message "!!!! ERROR: Failed to update RedHat system after $MAX_RETRIES attempts !!!!"
    return 1
}

main() {
    if [ "$EUID" -ne 0 ]; then
        echo "This script must be run as root. Please use sudo." >&2
        exit 1
    fi

    create_lock
    create_log_directory

    log_message "------------------------Starting system update"

    check_system_resources

    if ! check_internet; then
        exit 1
    fi

    if grep -qi "arch" "$RELEASE_FILE"; then
        update_arch
    elif [ -d /etc/apt ]; then
        update_apt
    elif grep -qiE "redhat|fedora|centos" "$RELEASE_FILE"; then
        update_redhat
    else
        log_message "!!!! ERROR: Unsupported or unrecognized Linux distribution !!!!!"
        exit 1
    fi

    log_message "--------------------------System update process completed"
}

main

Setting Up the Script

  1. Download the script.

  2. Make it executable: chmod +x update.sh

  3. Move it to a system directory: sudo mv update.sh /usr/local/bin/update

  4. Set proper permissions: sudo chmod 755 /usr/local/bin/update


Automating the Script with Cron

To schedule daily updates, create a cron job:

  1. Open the cron editor:

     sudo crontab -e
    
  2. Add the following line:

     0 0 * * * /usr/local/bin/update
    

This schedules the script to run every day at midnight.


Managing Log Files

To prevent log file accumulation, create another cron job to delete logs older than 30 days:

0 0 * * * find /var/log/system_updates/ -type f -mtime +30 -exec rm {} \;

Conclusion

By automating your system updates with this script, you can save time and ensure your Linux system is secure and up-to-date. It’s especially useful for servers and critical systems.

Give this script a try, and let me know how it works for you! Got questions or suggestions? Feel free to reach out via email.

Don’t forget to share this with your fellow Linux enthusiasts!

How to Automate System Updates Using a Custom Bash Script