168 lines
3.6 KiB
Bash
Executable File
168 lines
3.6 KiB
Bash
Executable File
#!/bin/sh
|
|
# pacsize -- display package sizes
|
|
#
|
|
# Copyright (C) 2014 Pierre Neidhardt <ambrevar@gmail.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
readonly myname='pacsize'
|
|
readonly myver='4.1.2'
|
|
|
|
calc_total () {
|
|
awk '{
|
|
total += $1
|
|
print
|
|
}
|
|
END {
|
|
printf ("%7s KIB TOTAL\n", total)
|
|
}'
|
|
}
|
|
|
|
error () {
|
|
echo "$@" >&2
|
|
}
|
|
|
|
## Print size and name. We round to the lowest integer, this makes output
|
|
## lighter.
|
|
filter () {
|
|
awk -F ": " \
|
|
'$0 ~ "^Name" {
|
|
pkg = $2
|
|
}
|
|
$0 ~ "^Installed Size" {
|
|
split($2, a, " ")
|
|
printf ("%4d%-3s %s\n", a[1], a[2], pkg)
|
|
}'
|
|
}
|
|
|
|
remove_duplicates () {
|
|
awk '! table[$0]++'
|
|
}
|
|
|
|
usage () {
|
|
cat <<EOF
|
|
Usage: ${1##*/} [OPTIONS] PACKAGES
|
|
${1##*/} -a [OPTIONS]
|
|
|
|
Display the size of PACKAGES. Duplicates are removed if any. The local database
|
|
is queried first; if the package is not found, the sync database is then used
|
|
for lookup.
|
|
|
|
Options:
|
|
|
|
-a: Process all installed packages.
|
|
-h: Show this help.
|
|
-n: Sort output by name.
|
|
-s: Sort output by size.
|
|
-t: Print total.
|
|
-V: Show version information.
|
|
|
|
Examples:
|
|
|
|
$ ${1##*/} -ast
|
|
Convenient way to keep track of big packages.
|
|
|
|
$ ${1##*/} \$(pactree -ld1 linux)
|
|
Print the size of linux and all its direct dependencies.
|
|
|
|
$ ${1##*/} -st \$(pacman -Qdtq)
|
|
Print a grand total of orphan packages, and sort by size.
|
|
EOF
|
|
}
|
|
|
|
version () {
|
|
echo "$myname $myver"
|
|
echo 'Copyright (C) 2014 Pierre Neidhardt <ambrevar@gmail.com>'
|
|
}
|
|
|
|
opt_sort=false
|
|
opt_all=false
|
|
opt_total=false
|
|
|
|
while getopts ":ahnstV" opt; do
|
|
case $opt in
|
|
a)
|
|
opt_all=true ;;
|
|
h)
|
|
usage "$0"
|
|
exit ;;
|
|
n)
|
|
opt_sort="sort -k3" ;;
|
|
s)
|
|
opt_sort="sort -h" ;;
|
|
t)
|
|
opt_total="calc_total" ;;
|
|
V)
|
|
version "$0"
|
|
exit ;;
|
|
?)
|
|
usage "$0"
|
|
exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
shift $(($OPTIND - 1))
|
|
|
|
## All-packages mode.
|
|
## We use a dedicated algorithm which is much faster than per-package mode.
|
|
## Unfortunately there is no easy way to select packages with this method.
|
|
if $opt_all; then
|
|
DBPath="$(awk -F "=[ \t]*" '/^[ \t]*DBPath[ \t]*=/{gsub(/[ \t]*$/, "", $2); print $2}' /etc/pacman.conf 2>/dev/null)"
|
|
[ -z "$DBPath" ] && DBPath="/var/lib/pacman"
|
|
|
|
if [ ! -d "$DBPath/local/" ]; then
|
|
error "Could not find local database in $DBPath/local/."
|
|
exit 1
|
|
fi
|
|
|
|
awk 'BEGIN {
|
|
split("B KiB MiB GiB TiB PiB EiB ZiB YiB", unit)
|
|
}
|
|
$0 == "%NAME%" {
|
|
getline pkg
|
|
}
|
|
$0 == "%SIZE%" {
|
|
getline size
|
|
i = 1
|
|
while (size > 2048) {
|
|
size /= 1024
|
|
i++
|
|
}
|
|
printf ("%4d%-3s %s\n", size, unit[i], pkg)
|
|
}' "$DBPath"/local/*/desc | { $opt_sort || cat ;} | { $opt_total || cat ;}
|
|
exit
|
|
fi
|
|
|
|
## Per-package mode.
|
|
if [ $# -eq 0 ]; then
|
|
error "Missing argument."
|
|
usage "$0"
|
|
exit 1
|
|
fi
|
|
|
|
## Remove this check if integrated to pacman.
|
|
if ! command -v pacman >/dev/null 2>&1; then
|
|
error "'pacman' not found."
|
|
exit 1
|
|
fi
|
|
|
|
{
|
|
## If package is not found locally (-Q), we use the sync database (-S). We
|
|
## use LC_ALL=C to make sure pacman output is not localized.
|
|
buffer=$(LC_ALL=C pacman -Qi "$@" 2>&1 1>&3 3>&- | cut -f2 -d "'")
|
|
[ -n "$buffer" ] && LC_ALL=C pacman -Si $buffer
|
|
} 3>&1 | filter | { $opt_sort || remove_duplicates ;} | { $opt_total || cat ;}
|
|
|
|
# vim: set noet:
|