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
Download the script.
Make it executable:
chmod +x update.shMove it to a system directory:
sudo mv update.sh /usr/local/bin/updateSet proper permissions:
sudo chmod 755 /usr/local/bin/update
Automating the Script with Cron
To schedule daily updates, create a cron job:
Open the cron editor:
sudo crontab -eAdd 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!





