Keeping your Linux system up-to-date is crucial for stability, security, and performance. Yet, Linux distributions vary in how they handle updates, cache management, and automatic upgrade services.
In this post, we’ll explore one of the scripts that I use in my basic system configuration toolkit. This script streamlines the process of updating and cleaning up various Linux distributions, allowing me to maintain multiple systems efficiently. Each script in this series is designed to handle a key area of system setup, so stay tuned as I continue sharing these solutions, tailored for seamless cross-platform functionality.
Certainly! Here’s a revised blog post explaining the latest version of the update.sh script. This post outlines how the script performs system updates, upgrades, and cleanups, as well as how it disables automatic updates on multiple distributions.
Overview of the update.sh Script
This script is designed to:
- Disable automatic updates to prevent potential interruptions, regardless of the distribution.
- Update the list of repositories and upgrade packages.
- Clean up package caches and unused dependencies, ensuring that the system runs smoothly with minimal bloat.
Supported distributions include:
- Ubuntu/Debian
- Fedora/CentOS/RHEL
- OpenSUSE
- Arch Linux
This cross-platform flexibility makes it an ideal tool for anyone managing different systems across a network.
#!/bin/bash -eu
# update.sh - Update package lists and upgrade the server to the latest versions.
# Function to get the distribution type
get_distro() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "$ID"
else
echo "unknown"
fi
}
# Disable automatic updates for each distribution
disable_auto_updates() {
case "$DISTRO" in
ubuntu|debian)
echo "==> Disabling apt-daily services on Debian/Ubuntu"
systemctl stop apt-daily.timer apt-daily-upgrade.timer
systemctl disable apt-daily.timer apt-daily-upgrade.timer
systemctl mask apt-daily.timer apt-daily-upgrade.timer
systemctl stop apt-daily.service apt-daily-upgrade.service
systemctl disable apt-daily.service apt-daily-upgrade.service
systemctl mask apt-daily.service apt-daily-upgrade.service
systemctl daemon-reload
;;
fedora|centos|rhel)
echo "==> Disabling dnf-automatic service on Fedora/CentOS/RHEL"
systemctl stop dnf-automatic.timer
systemctl disable dnf-automatic.timer
# Update /etc/dnf/automatic.conf to disable auto-updates
if [[ -f /etc/dnf/automatic.conf ]]; then
sudo sed -i 's/^apply_updates = .*/apply_updates = no/' /etc/dnf/automatic.conf
echo "==> Updated apply_updates to 'no' in /etc/dnf/automatic.conf"
fi
;;
arch)
echo "==> Arch Linux typically does not have automatic updates enabled by default"
# Optional: disable pamac update timers if used
systemctl disable pamac-mirrorlist.timer pamac-cleancache.timer pamac-update.timer 2>/dev/null
;;
opensuse*|suse)
echo "==> Disabling packagekit service on OpenSUSE"
systemctl stop packagekit.service
systemctl disable packagekit.service
# Update /etc/zypp/zypp.conf to disable auto-updates
if [[ -f /etc/zypp/zypp.conf ]]; then
sudo sed -i 's/^do_auto_updates = .*/do_auto_updates = false/' /etc/zypp/zypp.conf
echo "==> Updated do_auto_updates to 'false' in /etc/zypp/zypp.conf"
fi
;;
*)
echo "Automatic update disabling is not supported for $DISTRO"
;;
esac
}
# Function to update and upgrade packages based on distribution
update_and_upgrade() {
case "$DISTRO" in
ubuntu|debian)
echo "==> Updating and upgrading on Debian/Ubuntu"
apt-get update
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
fi
apt-get -y autoremove --purge
apt-get clean
;;
fedora|centos|rhel)
echo "==> Updating and upgrading on Fedora/CentOS/RHEL"
dnf makecache
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
dnf -y upgrade
fi
dnf -y autoremove
dnf clean all
;;
arch)
echo "==> Updating and upgrading on Arch Linux"
pacman -Sy
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
pacman -Syu --noconfirm
fi
pacman -Sc --noconfirm
;;
opensuse*|suse)
echo "==> Updating and upgrading on OpenSUSE"
zypper refresh
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
zypper update -y
fi
zypper clean --all
;;
*)
echo "Unsupported distribution: $DISTRO"
exit 1
;;
esac
}
# Main script execution
DISTRO=$(get_distro)
disable_auto_updates
update_and_upgrade
echo "System update and cleanup completed on $DISTRO."
Code Breakdown
Let’s dive into each section of the code and explain how it accomplishes the task across different distributions.
Detecting the Linux Distribution
To handle different package managers and settings across Linux distributions, the get_distro function checks the os-release file to identify the specific distribution.
get_distro() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "$ID"
else
echo "unknown"
fi
}
Disabling Automatic Updates
Automatic updates can be a problem, especially on servers where you need control over when packages are upgraded. Here’s how the disable_auto_updates function tackles this for each supported distribution:
- Ubuntu/Debian: Stops and disables
apt-dailyservices that trigger automatic updates. - Fedora/CentOS/RHEL: Disables
dnf-automaticby stopping its timer and settingapply_updates = noin/etc/dnf/automatic.conf. - OpenSUSE: Disables the
packagekitservice and updatesdo_auto_updates = falsein/etc/zypp/zypp.conf. - Arch Linux: Arch doesn’t enable automatic updates by default, but for completeness, we also check for
pamacupdate timers and disable them if present.
disable_auto_updates() {
case "$DISTRO" in
ubuntu|debian)
echo "==> Disabling apt-daily services on Debian/Ubuntu"
systemctl stop apt-daily.timer apt-daily-upgrade.timer
systemctl disable apt-daily.timer apt-daily-upgrade.timer
systemctl mask apt-daily.timer apt-daily-upgrade.timer
systemctl stop apt-daily.service apt-daily-upgrade.service
systemctl disable apt-daily.service apt-daily-upgrade.service
systemctl mask apt-daily.service apt-daily-upgrade.service
systemctl daemon-reload
;;
fedora|centos|rhel)
echo "==> Disabling dnf-automatic service on Fedora/CentOS/RHEL"
systemctl stop dnf-automatic.timer
systemctl disable dnf-automatic.timer
# Update /etc/dnf/automatic.conf to disable auto-updates
if [[ -f /etc/dnf/automatic.conf ]]; then
sudo sed -i 's/^apply_updates = .*/apply_updates = no/' /etc/dnf/automatic.conf
echo "==> Updated apply_updates to 'no' in /etc/dnf/automatic.conf"
fi
;;
arch)
echo "==> Arch Linux typically does not have automatic updates enabled by default"
systemctl disable pamac-mirrorlist.timer pamac-cleancache.timer pamac-update.timer 2>/dev/null
;;
opensuse*|suse)
echo "==> Disabling packagekit service on OpenSUSE"
systemctl stop packagekit.service
systemctl disable packagekit.service
# Update /etc/zypp/zypp.conf to disable auto-updates
if [[ -f /etc/zypp/zypp.conf ]]; then
sudo sed -i 's/^do_auto_updates = .*/do_auto_updates = false/' /etc/zypp/zypp.conf
echo "==> Updated do_auto_updates to 'false' in /etc/zypp/zypp.conf"
fi
;;
*)
echo "Automatic update disabling is not supported for $DISTRO"
;;
esac
}
This function executes the appropriate commands and configuration updates based on the detected distribution.
Performing Updates and Cleanup
Next, the update_and_upgrade function handles the package manager commands for updating and upgrading software on each supported system:
- Ubuntu/Debian: Uses
apt-getfor updating, upgrading, and cleaning up the package cache. - Fedora/CentOS/RHEL: Uses
dnffor the same tasks. - Arch Linux: Utilizes
pacmanfor package updates and cleanup. - OpenSUSE: Uses
zypperto refresh repositories, update packages, and clean cache.
update_and_upgrade() {
case "$DISTRO" in
ubuntu|debian)
echo "==> Updating and upgrading on Debian/Ubuntu"
apt-get update
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
apt-get -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade
fi
apt-get -y autoremove --purge
apt-get clean
;;
fedora|centos|rhel)
echo "==> Updating and upgrading on Fedora/CentOS/RHEL"
dnf makecache
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
dnf -y upgrade
fi
dnf -y autoremove
dnf clean all
;;
arch)
echo "==> Updating and upgrading on Arch Linux"
pacman -Sy
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
pacman -Syu --noconfirm
fi
pacman -Sc --noconfirm
;;
opensuse*|suse)
echo "==> Updating and upgrading on OpenSUSE"
zypper refresh
if [[ $UPDATE =~ true || $UPDATE =~ 1 ]]; then
zypper update -y
fi
zypper clean --all
;;
*)
echo "Unsupported distribution: $DISTRO"
exit 1
;;
esac
}
Running the Script
This script automatically detects the Linux distribution and applies the necessary steps. To use the script:
For a full upgrade, set the UPDATE environment variable before running:
UPDATE=true sudo ./update.sh
Run the script with sudo:
sudo ./update.sh
Save it as update.sh and make it executable:
chmod +x update.sh
Final Thoughts
This script is designed to manage updates across multiple Linux distributions, making it easier to maintain consistency and control across systems. With its cross-platform compatibility, it ensures that no matter the server or system, your updates are handled efficiently and without unwanted automatic interruptions.