2

So for a project as part of a work, I need to get the size of a Linux update.

I used the command:

aptitude search -SF '%p' --disable-columns '~U'

So I get the names of the packets whose need to be updated, but I need just the size for a script. I can use apt or aptitude for Ubuntu, Debian and I have the same thing to do with yum for Centos, RedHat.

I did some searching in the man command, but I can't find what I want. If somebody can help me? I was thinking it would be simple, but maybe I missed something.

galoget
  • 3,023
bastien
  • 23

2 Answers2

5

You can achieve that by doing the following steps:

First, install apt-show-versions package on the machine with:

sudo apt-get install -y apt-show-versions

With the following command you can get a list of packages that are upgradable:

apt-show-versions -u

This can be used to our advantage by concatenating this tool with apt-cache to recover the size of the package, let's see how this is done:

for package in `/usr/bin/apt-show-versions -u | tr ' ' / | cut -f1,6 -d'/' | tr / =` ; do echo -n $package ; sudo apt-cache show $package | grep '^Size:' | cut -d: -f2 ; done | sort -k2 -n

The previous command will give you a list of upgradable packages and their size in bytes in ascending order.

If you want to understand what is done in each step, here is a quick break down of the above command:

# Gives you a list of upgradable packages with their new available versions in format package_name=version
/usr/bin/apt-show-versions -u | tr ' ' / | cut -f1,6 -d'/' | tr / =

Get the size (in bytes) of each package that is upgradable

sudo apt-cache show $package | grep '^Size:'

Display the output in ascending order

sort -k2 -n

An example of the output of the previous command would be:

galoget@hackem:~$ for package in `/usr/bin/apt-show-versions -u | tr ' ' / | cut -f1,6 -d'/' | tr / =` ; do echo -n $package ; sudo apt-cache show $package | grep '
^Size:' | cut -d: -f2 ; done | sort -k2 -n

initramfs-tools:all=0.136ubuntu6.6 9248 systemd-sysv:amd64=245.4-4ubuntu3.7 10280 software-properties-common:all=0.98.9.5 10616 initramfs-tools-bin:amd64=0.136ubuntu6.6 10904 update-manager-core:all=1:20.04.10.7 11260 python-apt-common:all=2.0.0ubuntu0.20.04.5 17052 linux-base:all=4.5ubuntu3.6 17780 libasound2-data:all=1.2.2-2.1ubuntu2.4 20040 ubuntu-release-upgrader-core:all=1:20.04.33 23812 python3-software-properties:all=0.98.9.5 25124 alsa-ucm-conf:all=1.2.2-1ubuntu0.8 26484 systemd-timesyncd:amd64=245.4-4ubuntu3.7 28104 libprocps8:amd64=2:3.3.16-1ubuntu2.2 33016 libnetplan0:amd64=0.102-0ubuntu1~20.04.2 34608 libpam-runtime:all=1.3.1-5ubuntu4.2 37276 python3-update-manager:all=1:20.04.10.7 38176 libpam-modules-bin:amd64=1.3.1-5ubuntu4.2 41180 initramfs-tools-core:all=0.136ubuntu6.6 47744 libxmlb1:amd64=0.1.15-2ubuntu1~20.04.1 50520 libpam0g:amd64=1.3.1-5ubuntu4.2 55372 libudev1:amd64=245.4-4ubuntu3.7 77604 libnss-systemd:amd64=245.4-4ubuntu3.7 96096 python3-distupgrade:all=1:20.04.33 104100 netplan.io:amd64=0.102-0ubuntu1~20.04.2 117380 update-notifier-common:all=3.192.30.8 132392 python3-apt:amd64=2.0.0ubuntu0.20.04.5 154164 libpam-systemd:amd64=245.4-4ubuntu3.7 185812 apt-utils:amd64=2.0.6 216244 procps:amd64=2:3.3.16-1ubuntu2.2 232168 sosreport:amd64=4.1-1ubuntu0.20.04.2 245052 libpam-modules:amd64=1.3.1-5ubuntu4.2 260364 libsystemd0:amd64=245.4-4ubuntu3.7 270248 open-iscsi:amd64=2.0.874-7.1ubuntu6.2 283160 tmux:amd64=3.0a-2ubuntu0.3 292044 libasound2:amd64=1.2.2-2.1ubuntu2.4 334416 cloud-init:all=21.2-3-g899bfaa9-0ubuntu2~20.04.1 456404 open-vm-tools:amd64=2:11.2.5-2ubuntu1~ubuntu20.04.1 603812 openssl:amd64=1.1.1f-1ubuntu2.4 620068 libapt-pkg6.0:amd64=2.0.6 835288 ubuntu-advantage-tools:amd64=27.1~20.04.1 837368 apt:amd64=2.0.6 1295960 libssl1.1:amd64=1.1.1f-1ubuntu2.4 1319180 udev:amd64=245.4-4ubuntu3.7 1366316 systemd:amd64=245.4-4ubuntu3.7 3805892 snapd:amd64=2.49.2+20.04 30555628

In case you only want the size of the packages and add them to get the total size in bytes, you can use the following command:

galoget@ip-172-31-35-106:~$ for package in `/usr/bin/apt-show-versions -u | tr ' ' / | cut -f1,6 -d'/' | tr / =` ; do sudo apt-cache show $package | grep '^Size: ' | cut -d " " -f2 ; done | sort -k2 -n | awk '{ SUM += $1} END { print SUM }'

45245756

In my example the total size of the update will be 45245756 bytes, which is like 45.3 Megabytes, this can be verified by running:

galoget@hackem:~$ sudo apt upgrade

Reading package lists... Done Building dependency tree
Reading state information... Done Calculating upgrade... Done The following NEW packages will be installed: distro-info The following packages will be upgraded: alsa-ucm-conf apt apt-utils cloud-init initramfs-tools initramfs-tools-bin initramfs-tools-core libapt-pkg6.0 libasound2 libasound2-data libnetplan0 libnss-systemd libpam-modules libpam-modules-bin libpam-runtime libpam-systemd libpam0g libprocps8 libssl1.1 libsystemd0 libudev1 libxmlb1 linux-base netplan.io open-iscsi open-vm-tools openssl procps python-apt-common python3-apt python3-distupgrade python3-software-properties python3-update-manager snapd software-properties-common sosreport systemd systemd-sysv systemd-timesyncd tmux ubuntu-advantage-tools ubuntu-release-upgrader-core udev update-manager-core update-notifier-common 45 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 45.3 MB of archives. After this operation, 11.1 MB of additional disk space will be used. Do you want to continue? [Y/n] Y

As you can see, the size matches, so the command works perfectly.

galoget
  • 3,023
0

So with a friend we change some things. Reminder : I send a python scritp to get the size of the updates for apt and yum.

Their is the code in python :

def get_upgradable() :
    if os.path.isfile("/usr/bin/apt"):
        command = "apt list --upgradable 2>/dev/null | cut -d'/' -f1"
    elif os.path.isfile("/usr/bin/yum"):
        #command = "yum check-update 2>/dev/null | grep \".x86_64\" | cut -d' ' -f1"
        command="yum check-update | awk '/\S+\s+[0-9]\S+\s+\S+/ {print $1 }'"
    else :
        raise PkgManager("Not found package manager")
        return None
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, encoding='utf8')
    packages_name = []
    for out in process.stdout :
        packages_name.append(out[:-1])
    return packages_name

def get_yum_size(args, return_somme=True) : command = "yum info {pkg} | egrep "(Taille|Size)"" factor = {"k" : 1000, "M" : 1000000, "G" : 1000000000} somme = 0 sizes = [] for pkg in args : lines = subprocess.Popen(command.format(pkg=pkg), shell=True, stdout=subprocess.PIPE, encoding='utf8', ).stdout.readlines() infos = lines[-1][:-1].split(' ') size = float(infos[-2])factor[infos[-1]] sizes.append(size) somme += size if return_somme : return somme return sizes

def get_apt_size(*args, return_somme=True) : command = "apt-cache --no-all-versions show {pkg} | grep "^Size" | cut -d' ' -f2" sizes = [] somme = 0 for pkg in args : size = int(subprocess.Popen(command.format(pkg=pkg), shell=True, stdout=subprocess.PIPE, encoding='utf8' ).stdout.read()) sizes.append(size) somme += size if return_somme : return somme return sizes

def get_size(args, kwargs) : if os.path.isfile("/usr/bin/apt"): return get_apt_size(args, kwargs) elif os.path.isfile("/usr/bin/yum"): return get_yum_size(*args, kwargs) else : raise PkgManager("Not found package manager")

And you call it in the main code with :

get_size(*get_upgradable())

If you try, the output will be : 9780000000

That's the all size of the updates in bytes.

bastien
  • 23