ambevar-dotfiles/.scripts/pacsize

134 lines
4.3 KiB
Plaintext
Raw Normal View History

#!/bin/sh
2013-12-24 13:24:58 +01:00
# pacsize -- display package sizes
#
# Copyright (C) 2013 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/>.
_printhelp()
{
cat <<EOF
Usage: ${1##*/} [OPTIONS] PACKAGES
2013-12-24 11:29:49 +01:00
${1##*/} -a [OPTIONS]
2013-12-24 13:24:58 +01:00
Display package sizes. Output can be sorted by name or size, while removing
duplicates if any. A grand total can be printed at the end. By default, search
the sync database. For faster processing and local package support, you can use
the local databases. If 'expac' is found in the path, it will be used for faster
processing.
2013-12-24 13:24:58 +01:00
Options:
-a: All installed packages. Implies -q.
2013-06-25 22:56:10 +02:00
-h: Show this help.
-n: Output is sorted by name.
2013-06-25 22:56:10 +02:00
-q: Uses installed packages database instead of repos database. It speeds up
queries and allows displaying size of local packages not available in
repos.
-s: Output is sorted by size.
2013-12-24 12:12:25 +01:00
-t: Print total.
2013-06-25 22:56:10 +02:00
2013-12-24 13:24:58 +01:00
Examples:
${1##*/} -ast
Convenient way to monitor big packages.
2013-12-29 10:17:17 +01:00
${1##*/} -q \$(pactree -ld1 linux)
2013-12-24 13:24:58 +01:00
Print the size of linux and its direct dependencies.
2013-12-29 10:17:17 +01:00
${1##*/} -qst \$(pacman -Qdtq)
2013-12-24 13:24:58 +01:00
Print a grand total of orphan packages, and sort by size.
EOF
}
2013-12-24 13:24:58 +01:00
cmd="S"
total_size=0
opt_sort=false
opt_all=false
opt_total=0
2013-12-24 12:12:25 +01:00
while getopts ":ahnqst" opt; do
case $opt in
2013-12-24 11:29:49 +01:00
a)
2013-12-24 13:24:58 +01:00
opt_all=true
cmd="Q" ;;
h)
_printhelp "$0"
2013-12-24 13:24:58 +01:00
exit ;;
n)
2013-12-24 13:24:58 +01:00
opt_sort="sort -uk3" ;;
q)
2013-12-24 13:24:58 +01:00
cmd="Q" ;;
s)
2013-12-24 13:24:58 +01:00
opt_sort="sort -n" ;;
2013-12-24 12:12:25 +01:00
t)
2013-12-24 13:24:58 +01:00
opt_total=1 ;;
?)
_printhelp "$0"
exit 1 ;;
:)
echo "Missing argument."
_printhelp "$0"
exit 1 ;;
esac
done
shift $(($OPTIND - 1))
2013-12-24 11:29:49 +01:00
## If expac is available, use it since it is much faster.
2013-12-24 13:24:58 +01:00
if ! command -v expac >/dev/null; then
expac -HK -$cmd '%6m %n' "$@" | awk -v sum=$opt_total '{sub(/[\.,]00/,""); if(sum) total+=$1; printf("%6s %s %s\n",$1,$2,$3)} END {if(sum) print total, "KiB TOTAL"}' | ($opt_sort || cat)
2013-12-24 11:29:49 +01:00
exit
fi
2013-12-24 12:21:44 +01:00
## All-packages mode. We use a different algorithm which is much faster than for a list of packages.
2013-12-24 13:24:58 +01:00
if $opt_all; then
2013-12-24 11:29:49 +01:00
DBPath=$(awk -F = '/^ *DBPath/{print $2}' /etc/pacman.conf)
[ ! -d "$DBPath" ] && DBPath="/var/lib/pacman/"
2013-12-24 12:21:44 +01:00
[ ! -d "$DBPath/local/" ] && exit
2013-12-24 11:29:49 +01:00
2013-12-24 13:24:58 +01:00
awk -v sum=$opt_total '/^%NAME%/ {getline;pkg=$0} /^%SIZE%/ {getline; size=$0/1024; if (sum) total+=size; printf("%6s KiB %s\n", size, pkg)} END {if (sum) print total, "KiB TOTAL"}' "$DBPath"/local/*/desc | ($opt_sort || cat)
2013-12-24 11:29:49 +01:00
exit
fi
## Per-package mode
if [ $# -eq 0 ]; then
2013-12-24 12:21:44 +01:00
echo "Missing argument." >&2
_printhelp "$0"
exit 1
fi
2013-12-24 12:21:44 +01:00
if ! command -v pacman >/dev/null; then
echo "You need the pacman package manager." >&2
exit 1
fi
## We use the 'tzdata' package as reference for the output fields, because it is
## almost always installed. This let's us access the entry of pacman's output
## independently of the current locale.
pacman_var_list="$(pacman -Qi tzdata | cut -f1 -d':')"
if [ -z "$pacman_var_list" ]; then
echo "Could not get pacman's variables." >&2
exit 1
2013-10-29 21:49:48 +01:00
fi
2013-12-24 12:21:44 +01:00
pacman_name="$(echo "$pacman_var_list" | sed -n '1{p;q}')"
pacman_size="$(echo "$pacman_var_list" | sed -n '15{p;q}')"
2013-10-29 21:49:48 +01:00
2013-12-24 12:12:25 +01:00
## We use external variable for awk to fit current locales. In the following
2013-12-24 11:29:49 +01:00
## command, we strip the decimals. This makes output lighter. The line below
## does not do it.
2013-12-24 12:12:25 +01:00
# '$0 ~ pkg {pkgname=$2} $0 ~ filter {printf("%13s %s\n", $2, pkgname)}'
2013-12-24 13:24:58 +01:00
pacman -${cmd}i "$@" 2>/dev/null | awk -F ": " -v filter="$pacman_size" -v pkgname="$pacman_name" -v sum=$opt_total \
'$0 ~ pkgname {pkg=$2} $0 ~ filter {gsub(/[\.,].*/,""); if(sum) total+=$2; printf("%6s KiB %s\n", $2, pkg)} END {if(sum && total) print total, "KiB TOTAL"}' | ($opt_sort || cat)