# 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**

```bash
#!/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:
    
    ```bash
    sudo crontab -e
    ```
    
2. Add the following line:
    
    ```bash
    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:

```bash
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!
