Last active
December 31, 2025 12:09
-
-
Save h908714124/7325d8213b81dce638a20ab9866d414d to your computer and use it in GitHub Desktop.
update-fedora
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| batch_mode=false | |
| suggest_rawhide=false | |
| synopsis() { | |
| tput bold | |
| echo "USAGE" | |
| tput sgr0 | |
| echo " update-fedora [-y] [-r]" | |
| echo | |
| tput bold | |
| echo "OPTIONS" | |
| tput sgr0 | |
| echo " -y" | |
| echo " Batch mode. Never reboot the system." | |
| echo " Never check for system upgrades." | |
| echo " -r" | |
| echo " Suggest rawhide if applicable." | |
| } | |
| show_interactive_help() { | |
| echo " s - show available updates" | |
| echo " o - prepare offline update" | |
| echo " u - regular update (no reboot)" | |
| echo " q - quit" | |
| echo " h - help" | |
| } | |
| release_type() { | |
| sed -n -E 's/^RELEASE_TYPE=(\S+)/\1/p' /etc/os-release | |
| } | |
| os_release() { | |
| sed -n -E 's/^VERSION_ID=(\S+)/\1/p' /etc/os-release | |
| } | |
| target_release() { | |
| local result | |
| local current=$(os_release) | |
| if [[ $(release_type) != "stable" ]]; then | |
| echo $current | |
| return 0 | |
| fi | |
| local metainfo=/usr/share/metainfo/org.fedoraproject.fedora.metainfo.xml | |
| if [[ -f $metainfo ]]; then | |
| result=$(xmllint --xpath "/component/releases//release[@type='stable']/@version" $metainfo | \ | |
| sed -n -E 's/.*[=]["]([0-9]+)["].*/\1/p' | \ | |
| sort -rn | \ | |
| head -1) | |
| else | |
| result=$(curl -s "https://fedoraproject.org/releases.json" | \ | |
| jq -r ".[]|select( .arch == \"$(uname -m)\") |.version" | \ | |
| sort -rn | \ | |
| head -1) | |
| fi | |
| if (( result >= current )); then | |
| echo $result | |
| else | |
| echo $current | |
| fi | |
| } | |
| is_update_prepared() { | |
| sudo dnf offline status | grep -F -q "offline reboot" | |
| } | |
| check_updates_available() { | |
| [[ $(dnf check-update --refresh 2> /dev/null) ]] | |
| } | |
| system_update() { | |
| local target=$1 | |
| sudo dnf -y system-upgrade download --releasever=$target && { | |
| read -p "A system update is prepared. Would you like to reboot right now? [y/N] " | |
| [[ $REPLY =~ [yY] ]] && sudo dnf -y offline reboot | |
| } | |
| } | |
| update_apply() { | |
| sudo dnf -y update --refresh | |
| } | |
| offline_prepare() { | |
| sudo dnf -y update --refresh --offline && { | |
| read -p "An update is prepared. Would you like to reboot right now? [y/N] " | |
| [[ $REPLY =~ [yY] ]] && sudo dnf -y offline reboot | |
| } | |
| } | |
| default_action() { | |
| local opt options | |
| options=$(getopt -o "yrh" -- "$@") | |
| (( $? == 0 )) || { | |
| synopsis | |
| return 1 | |
| } | |
| for opt in $options; do | |
| case $opt in | |
| -y) | |
| batch_mode=true | |
| ;; | |
| -r) | |
| suggest_rawhide=true | |
| ;; | |
| -h) | |
| synopsis | |
| return 0 | |
| ;; | |
| --) | |
| ;; | |
| *) | |
| echo "Unknown parameter: $opt" | |
| synopsis | |
| return 1 | |
| ;; | |
| esac | |
| done | |
| if is_update_prepared; then | |
| $batch_mode && { | |
| echo "An update is prepared. Please disable batch mode and try again." | |
| return 1 | |
| } | |
| read -p "An update is prepared. Would you like to reboot right now? [y/N] " | |
| [[ $REPLY =~ [yY] ]] && sudo dnf -y offline reboot | |
| return 0 | |
| fi | |
| check_updates_available && { | |
| if $batch_mode; then | |
| update_apply | |
| return 0 | |
| fi | |
| while true; do | |
| read -p "An update is available. Press \"h\" for help. [s]how [o]ffline [u]update [q]uit ? " | |
| case $REPLY in | |
| s) | |
| dnf check-update | |
| ;; | |
| o) | |
| offline_prepare | |
| return 0 | |
| ;; | |
| u) | |
| update_apply | |
| return 0 | |
| ;; | |
| q) | |
| return 0 | |
| ;; | |
| h) | |
| show_interactive_help | |
| ;; | |
| esac | |
| done | |
| } | |
| echo "The system is up-to-date." | |
| $batch_mode && { | |
| echo "Disable batch mode to check for system updates." | |
| return 0 | |
| } | |
| local current=$(os_release) | |
| local target=$(target_release) | |
| if (( current == target )); then | |
| if $suggest_rawhide && [[ $(release_type) = "stable" ]]; then | |
| read -p "Would you like to upgrade to rawhide? [y/N] " | |
| [[ $REPLY =~ [yY] ]] && system_update rawhide | |
| fi | |
| else | |
| echo "A system update to fedora $(( current + 1 )) is available." | |
| read -p "Would you like to download it now? [y/N] " | |
| [[ $REPLY =~ [yY] ]] && system_update $(( current + 1 )) | |
| fi | |
| return 0 | |
| } | |
| return 2> /dev/null || { | |
| default_action "$@" | |
| exit $? | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Keeping fedora updated is a bit hard. It's not a rolling distro, unless you use rawhide. This script simplifies the task, because it knows when to do the system-update. I keep it in
~/.local/bin/update-fedoraand run it frequently. I also like to disable the notifications from Discover.