0

I am writing a shell script that will ask me if I'd like to check my system for updates when I log in. If I say yes, it checks and lists the packages to be upgraded. Then, it asks me if I would like to upgrade those packages. I would like the command that asks me if I'd like to upgrade the packages to only run when there is one or more package that needs to be upgraded that was listed after sudo apt update && apt list --upgradeable. How can I do this? Here is my script so far:

read -r -p "Would you like to check your system for updates? [Y/n] " input
case $input in
[yY][eE][sS]|[yY])
sudo apt update && apt list --upgradeable 
read -r -p "Would you like to update your system? [Y/n] " input
case $input in
[yY][eE][sS]|[yY])
sudo apt upgrade && sudo apt autoremove && sudo apt autoclean
;;
[nN][oO]|[nN])
clear
;;
*)
clear && echo "Invalid input..."
;;
esac
;;
[nN][oO]|[nN])
clear
;;
*)
clear && echo "Invalid input..."
;;
esac

It basically needs to be like this: if this bit of text is in the previous command's output, then run the next command.

Any help is much appreciated. Thanks!

2 Answers2

2

Get the number of available updates with:

/usr/lib/update-notifier/apt-check
# returns (for example) 12;4

/usr/lib/update-notifier/apt-check --human-readable
# returns (for example)
  12 packages can be updated.
  4 updates are security updates.

/usr/lib/update-notifier/apt-check |& cut -d";" -f1
# returns (for example) 12

To test if there are available updates, use the last command and test his ouput against 0.

Here is a simple script that will do your stuff
Note that it does not handle bad inputs, only catches '', 'yes', 'YeS', 'y', 'Y' to continue proceeding. If no 'yes' input, then simply exit script.

#!/bin/bash

read -r -p "Would you like to check your system for updates? [Y/n] " response
  response=${response,,} # tolower
  if ! ([[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]); then
    exit
  fi
sudo apt update > /dev/null 2>&1
nUpgradables=$(/usr/lib/update-notifier/apt-check |& cut -d";" -f1)

if [ $nUpgradables -gt 0 ]; then
  echo ${nUpgradables}" packages can be updated"
  read -r -p "Would you like to update your system? [Y/n] " input
  response=${response,,} # tolower
  if ! ([[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]); then
    exit
  fi
  sudo apt-get -f install # that is good to do too
  sudo apt upgrade        # upgrade, not 'upgrades'
  sudo apt autoremove
  sudo apt autoclean
else
  echo "No upgrade available"
fi
cmak.fr
  • 8,976
1
#!/bin/bash

# update package list.
aptitude --quiet=2 update

# count upgradeable packages.
read -r c < <(aptitude --quiet=2 search '?narrow(?upgradable, ?not(?action(hold)))' | wc -l)

while true; do
    (( $c <= 0 )) && break
    read -r -p "You have $c upgradable packages, would you like to upgrade? [Y/n] " i
    case ${i,,} in
        [y]|[yes])
            aptitude upgrade # --assume-yes --quiet=2
            break
            ;;
        [n]|[no])
            echo "No action taken..."
            break
            ;;
        *)
            echo "Invalid input..."
            continue
            ;;
    esac
done

exit 0

Version 2

#!/bin/bash

# update package list.
apt-get --quiet=2 update

# count upgradeable packages.
read -r c < <(apt-get --no-act --quiet=2 upgrade | grep -c '^Inst')

while true; do
    (( $c <= 0 )) && break
    read -r -p "You have $c upgradable packages, would you like to upgrade? [Y/n] " i
    case ${i,,} in
        [y]|[yes])
            apt-get upgrade # --assume-yes --quiet=2
            break
            ;;
        [n]|[no])
            echo "No action taken..."
            break
            ;;
        *)
            echo "Invalid input..."
            continue
            ;;
    esac
done

exit 0