5

Sometimes when I want to discover a new software to use I have to compare between multiple packages. One of the important factors for me is the package size since I often tend to use light packages for everything.

The pacman -Ss command Is very useful but I would really love to have the size of packages too so I can compare. I tried pacman -Ssi but it doesn't work. Is there any way to add some info to the result of pacman -Ss?

I also tried pacman -Ss -p --print-format "%n: %s" but that didn't work either.

2 Answers 2

3

You can use pacman -Si to get the Installed Size of a package. So it all becomes a matter of awk scripting.

You can define the following function and use it.

pkgsize(){ 
    pacman -Ss $@ | awk '{if(NR%2) {system("pacman -Si "$1" | grep Ins | cut -d\":\" -f 2 | tr -d \" \n\" "" "); printf " "$1"$";} else print $0}' | sort -h | tr "$" "\n" 
}

You can also do it like this if you want:

pkgsize(){      
    pacman -Ss video edit | awk 'NR%2 { while("pacman -Si "$1 | getline line) if (line ~ /Ins/) { split(line,a,/:/);printf a[2] };print $1""}'
}

I just discovered there is a much easier approach!

pkgsize(){ expac -SsH M "%m: %n$\t%d" $@ | sort -h | tr '$' '\n'}
2
  • 1
    Often number of dependencies worry me more than size of package. +1 Jun 1, 2019 at 14:48
  • 2
    @RuiFRibeiro more important than that is the number of deps I don't already have installed. I don't know how to figure that other than running pacman -S and looking at the result. Jun 2, 2019 at 4:05
0

Here is another more explicit solution written in bash to collect package sizes including all minimum dependencies.

# bc compatible math form 
# ex. 10KiB + 9MiB => 10*kib + 9*mib
function math () { 
  printf '%s\n' "$@" \
  | sed -E 's/(([0-9]+)[[:space:]]*([a-zA-Z]+))/\2*\3/g' \
  | sed -E 's,[^a-zA-Z0-9+*/. -]+,,g' \
  | tr '[:upper:]' '[:lower:]' || true
}

# bc wrapper with optional SCALE env to round up
function calc () {
  [ -z "$1" ] \
  && echo 0 \
  && return 0

  local scale=""
  local result=
  local form="$(math "$@")"

  { [ -z "$form" ] \
  || [[ "$form" =~ ^[+*/-].*$ ]]; } \
    && local form="0$form"

  if [[ "$SCALE" =~ ^[0-9]{1}$ ]]; then
    local script="scale=$SCALE;x=((10^$SCALE)*($form)+0.5)/(10^$SCALE); print x"
    printf "%.${SCALE}f" "$(bc -l <<EOF
  $CALC_VARS
  $script
EOF
)"
  else
    local script="x=($form); print x"
    bc -l <<EOF
  $CALC_VARS
  $script
EOF
  fi
}

# calc wrapper to pass byte relevant units
function bytecalc () {
  CALC_VARS="s=512
kib=1024
mib=1024*kib
gib=1024*mib
tib=1024*gib
kb=1000
mb=1000*kb
gb=1000*mb
tb=1000*gb" calc "$@"
}

function Package::size () {
  [ -z "$SEEN" ] \
    && local SEEN=`mktemp` \
    && local cleanup=${#FUNCNAME[@]}
  
  local sum=0
  for pkg in "$@"; do
    cat "$SEEN" | grep -qE "^$pkg$" \
      && continue
    
    local info=`pacman -Qi "$pkg" 2>/dev/null || pacman -Si "$pkg"`
    local size=`grep "Installed Size" <<<"$info" \
                | cut -d: -f2 | xargs \
                | tr , . || true`
    local -a deps=(`grep "Depends On" <<<"$info" \
                | cut -d: -f2 \
                | grep -oE "($| )[a-z][a-z0-9_.-]*" || true`)
    echo "$pkg" >>"$SEEN"

    test "${#deps[@]}" -gt 0 \
      && echo "lookup deps for '$pkg': ${deps[@]}" >&2 \
      && local depsize=$(Package::size "${deps[@]}" || true) \
      || local depsize=0
    
    sum=$(SCALE=0 bytecalc "${sum:-0} + ${size:-0} + ${depsize:-0}")
  done
  test ${cleanup} -eq ${#FUNCNAME[@]} && rm "$SEEN"

  echo "$sum"
}

Local tests

On my machine Package::size konsole results in 1973756405 bytes which still feels a little bit monolithic. On the other hand, if you want to build a custom edgy distro with only konsole installed, it's niche is at least backed with lots of framework potential.

Sidenote on database sync

Note that this function queries the local database first and queries the remote data at failure. So it is possible that local and remote dependency lists are not in sync, which will return wrong results most probably.

Bash variable scopes

I do not consider bash a bug as a whole, but the fact that local variables are visibile within the regarding function's children functions I do.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .