有时,当我想发现一个新软件来使用时,我必须在多个软件包之间进行比较。对我来说,重要的因素之一是包装尺寸,因为我经常倾向于使用轻型包装来处理所有事情。
该pacman -Ss
命令非常有用,但我真的很想知道包的大小,以便我可以进行比较。我尝试过pacman -Ssi
,但没有成功。有什么办法可以在结果中添加一些信息吗pacman -Ss
?
我也尝试过,pacman -Ss -p --print-format "%n: %s"
但这也没有用。
答案1
您可以使用它pacman -Si
来获取包的安装大小。所以这一切都变成了 awk 脚本的问题。
您可以定义以下函数并使用它。
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"
}
如果你愿意,你也可以这样做:
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""}'
}
我刚刚发现有一种更简单的方法!
pkgsize(){ expac -SsH M "%m: %n$\t%d" $@ | sort -h | tr '$' '\n'}
答案2
这是用 bash 编写的另一个更明确的解决方案,用于收集包大小,包括所有最小依赖项。
# 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"
}
本地测试
在我的机器上,Package::size konsole
结果1973756405 bytes
仍然感觉有点单一。另一方面,如果您想构建一个仅安装 konsole 的自定义前卫发行版,那么它的利基市场至少有大量框架潜力的支持。
关于数据库同步的旁注
注意该函数先查询本地数据库,失败时再查询远程数据。因此,本地和远程依赖项列表可能不同步,这很可能会返回错误的结果。
Bash 变量作用域
我不认为 bash 是一个错误,但事实是局部变量在相关函数的子函数中是可见的。