Created
June 5, 2025 16:07
-
-
Save ThinGuy/355686867e3e804f597851bd68c3ae49 to your computer and use it in GitHub Desktop.
Script to calculate all vs installed packages on Ubuntu
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 | |
# An Ubuntu Package Counter - Counts all vs installed and creates manifests by component for current release. | |
# Set parameters | |
export TITLE='AWS Summit Washington, DC 2025' | |
export PROG="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/${BASH_SOURCE[0]##*/}" | |
export DARCH=$(dpkg --print-architecture) | |
export REL=$(lsb_release -cs 2>/dev/null|sed 's/^.*$/\u&/') | |
export VER=$(lsb_release -rs 2>/dev/null) | |
[[ -f /etc/machine-id ]] && { export MID=$(cat /etc/machine-id); } | |
[[ -z ${MID} && -f /var/lib/dbus/machine-id ]] && { export MID=$(cat /var/lib/dbus/machine-id); } | |
[[ -z ${MID} ]] && { export MID=unknown; } | |
# This array is for main since the sections won't start with a component | |
declare -ag SECTIONS=(admin cli-mono comm database debug devel doc editors education electronics embedded fonts games gnome gnu-r gnustep graphics hamradio haskell httpd interpreters introspection java javascript kde kernel libdevel libs lisp localization mail math metapackages misc net news ocaml oldlibs otherosfs perl php python ruby rust science shells sound tasks tex text utils vcs video web x11 xfce zope) | |
# Cleanup old manifests | |
find ~/ -maxdepth 1 -type f -regextype "posix-extended" -iregex '.*ubuntu-.*\.(installed|all).manifest' -delete | |
# Begin output | |
printf "\n\e[1G\e[0;1;38;2;233;84;32mUbuntu Pro\e[0;1m™ Swag Script - ${TITLE}\e[0m\n\n\e[2G\e[1mSystem Info:\e[0m $(ubuntu-distro-info --series=${REL,,} -f)\n" | |
[[ -n ${MID} ]] && { printf "\e[2G\e[1mMachine ID:\e[0m\x20${MID}\n\n"; } | |
# Create arrays of all vs installed packages by component | |
printf "\e[2G\e[1mParsing APT components...\e[0m\n" | |
printf "\e[3G - Parsing \e[1mMain\e[0m\n" | |
declare -ag MAIN_LIST=($((printf '%s\n' ${SECTIONS[@]}|xargs -rn1 -P0 bash -c 'apt -qq 2>/dev/null list "?section(^$0$)"'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
declare -ag MAIN_LIST_INSTALLED=($((printf '%s\n' ${SECTIONS[@]}|xargs -rn1 -P0 bash -c 'apt -qq 2>/dev/null list --installed "?section(^$0$)"'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
printf "\e[3G - Parsing \e[1mUniverse\e[0m\n" | |
declare -ag UNIVERSE_LIST=($((apt -qq 2>/dev/null list '?section(^universe/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
declare -ag UNIVERSE_LIST_INSTALLED=($((apt -qq 2>/dev/null list --installed '?section(^universe/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
printf "\e[3G - Parsing \e[1mMultiverse\e[0m\n" | |
declare -ag MULTIVERSE_LIST=($((apt -qq 2>/dev/null list '?section(^multiverse/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
declare -ag MULTIVERSE_LIST_INSTALLED=($((apt -qq 2>/dev/null list --installed '?section(^multiverse/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
printf "\e[3G - Parsing \e[1mRestricted\e[0m\n" | |
declare -ag RESTRICTED_LIST=($((apt -qq 2>/dev/null list '?section(^restricted/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
declare -ag RESTRICTED_LIST_INSTALLED=($((apt -qq 2>/dev/null list --installed '?section(^restricted/)'|sed -r '/^$/d')|sort -uV|awk -F"/| " '{OFS="|";print $1,$3}')) | |
# Display Package Counts | |
printf "\n\e[2G\e[1mPackages by component (installed):\e[0m\n\n" | |
printf "\e[3G - Main: \e[1m${#MAIN_LIST_INSTALLED[@]}\e[0m\n" | |
printf "\e[3G - Universe: \e[1m${#UNIVERSE_LIST_INSTALLED[@]}\e[0m\n" | |
printf "\e[3G - Multiverse: \e[1m${#MULTIVERSE_LIST_INSTALLED[@]}\e[0m\n" | |
printf "\e[3G - Restricted: \e[1m${#RESTRICTED_LIST_INSTALLED[@]}\e[0m\n" | |
export TOTAL_INSTALLED=$((${#MAIN_LIST_INSTALLED[@]}+${#UNIVERSE_LIST_INSTALLED[@]}+${#MULTIVERSE_LIST_INSTALLED[@]}+${#RESTRICTED_LIST_INSTALLED[@]})) | |
printf "\n\e[2G\e[1mPackages by component (all):\e[0m\n\n" | |
printf "\e[3G - Main: \e[1m${#MAIN_LIST[@]}\e[0m\n" | |
printf "\e[3G - Universe: \e[1m${#UNIVERSE_LIST[@]}\e[0m\n" | |
printf "\e[3G - Multiverse: \e[1m${#MULTIVERSE_LIST[@]}\e[0m\n" | |
printf "\e[3G - Restricted: \e[1m${#RESTRICTED_LIST[@]}\e[0m\n" | |
export TOTAL_ALL=$((${#MAIN_LIST[@]}+${#UNIVERSE_LIST[@]}+${#MULTIVERSE_LIST[@]}+${#RESTRICTED_LIST[@]})) | |
printf "\n\e[2G\e[1mTotal Packages:\e[0m\n" | |
printf "\e[3G - Installed: \e[1m${TOTAL_INSTALLED}\e[0m\n" | |
printf "\e[3G - All: \e[1m${TOTAL_ALL}\e[0m\n" | |
# Create manifests | |
printf "\n\e[2G\e[1mCreating Package + Version manifests...\e[0m\n" | |
(printf '%s\n' ${MAIN_LIST[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_main_${DARCH}.all.manifest | |
(printf '%s\n' ${UNIVERSE_LIST[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_universe_${DARCH}.all.manifest | |
(printf '%s\n' ${MULTIVERSE_LIST[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_multiverse_${DARCH}.all.manifest | |
(printf '%s\n' ${RESTRICTED_LIST[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_restricted_${DARCH}.all.manifest | |
(printf '%s\n' ${MAIN_LIST_INSTALLED[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_main_${DARCH}.installed.manifest | |
(printf '%s\n' ${UNIVERSE_LIST_INSTALLED[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_universe_${DARCH}.installed.manifest | |
(printf '%s\n' ${MULTIVERSE_LIST_INSTALLED[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_multiverse_${DARCH}.installed.manifest | |
(printf '%s\n' ${RESTRICTED_LIST_INSTALLED[@]}|sed -r 's/\|/\t/g')| tee 1>/dev/null ~/ubuntu-${REL,,}_restricted_${DARCH}.installed.manifest | |
declare -ag MANIFESTS=($((find ~/ -maxdepth 1 -type f -regextype "posix-extended" -iregex '.*ubuntu-.*\.(installed|all).manifest'|sort -uV)|sed -r '/main.*|universe.*/!H;//p;$!d;g;s/\n//')) | |
# Show location of manifest files | |
printf "\n\e[3G\e[1mAll Packages:\e[0m\n\n" | |
(printf '\e[3G - %s\n' ${MANIFESTS[@]}|sed -r '/\.installed\.manifest/d'|sed -r '/main.*|universe.*/!H;//p;$!d;g;s/\n//') | |
printf "\n\e[4G\e[1mInstalled Packages:\e[0m\n\n" | |
(printf '\e[3G - %s\n' ${MANIFESTS[@]}|sed -r '/\.all\.manifest/d'|sed -r '/main.*|universe.*/!H;//p;$!d;g;s/\n//') | |
# Print message that we are done | |
printf "\n\n\e[1G\e[0;1;38;2;233;84;32mUbuntu Pro\e[0;1m™\e[0m Swag Script Complete\e[0m\n\nThank you for visiting Canonical at ${TITLE%%,*}\x21\n\n" | |
# Clean up vars | |
unset $(grep -oP '(?<=^declare -ag |export )[^=]+' ${PROG}|paste -sd' ') | |
# Script complete. | |
exit 0 |
Author
ThinGuy
commented
Jun 5, 2025
craigbender@cbpc:~/$ ./aws-pro-counter-sh
Ubuntu Pro™ Swag Script - AWS Summit Washington, DC 2025
System Info: Ubuntu 25.04 "Plucky Puffin"
Machine ID: b643c14980804fd7a70d3869389c8b11
Parsing APT components...
- Parsing Main
- Parsing Universe
- Parsing Multiverse
- Parsing Restricted
Packages by component (installed):
- Main: 2388
- Universe: 2108
- Multiverse: 10
- Restricted: 4
Packages by component (all):
- Main: 5915
- Universe: 67234
- Multiverse: 1095
- Restricted: 267
Total Packages:
- Installed: 4510
- All: 74511
Creating Package + Version manifests...
All Packages:
- /home/craigbender/ubuntu-plucky_main_amd64.all.manifest
- /home/craigbender/ubuntu-plucky_universe_amd64.all.manifest
- /home/craigbender/ubuntu-plucky_multiverse_amd64.all.manifest
- /home/craigbender/ubuntu-plucky_restricted_amd64.all.manifest
Installed Packages:
- /home/craigbender/ubuntu-plucky_main_amd64.installed.manifest
- /home/craigbender/ubuntu-plucky_universe_amd64.installed.manifest
- /home/craigbender/ubuntu-plucky_multiverse_amd64.installed.manifest
- /home/craigbender/ubuntu-plucky_restricted_amd64.installed.manifest
Ubuntu Pro™ Swag Script Complete
Thank you for visiting Canonical at AWS Summit Washington!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment