NOTE: If you have AUR packages installed, the script may not accurately distinguish between explicit packages and dependencies. Running the script a second time is advisable to verify them. The script includes a commented section (disabled to improve performance); if you have AUR packages, please uncomment that section and run the script normally.
Code: Select all
#!/bin/bash
# ============================================
# pacmandb-normalize
# Tries to rebuild (a damaged) Pacman database
# marking packages as explicit or dependencies
# ============================================
# Get the list of all installed packages
readarray -t all_packages < <(pacman -Qq)
declare -A dependencies
explicit_packages=()
# Mark all packages as dependencies (clean base)
sudo pacman -D --asdeps $(pacman -Qqe) >/dev/null 2>&1
get_package_dependencies() {
LC_ALL=en_us pacman -Qi "$1" | awk -F ': ' '/^Depends On/ {print $2}' | tr ' ' '\n' | grep -v "^None$"
}
echo "Identifying dependencies..."
for package in "${all_packages[@]}"; do
while IFS= read -r dependency; do
[[ -n "$dependency" ]] && dependencies["$dependency"]=1
done < <(get_package_dependencies "$package")
done
echo "Marking explicit packages..."
for package in "${all_packages[@]}"; do
if [[ -z "${dependencies[$package]}" ]]; then
explicit_packages+=("$package")
sudo pacman -D --asexplicit "$package" >/dev/null 2>&1
fi
done
# Verification
#echo "Verifying classification..."
#for package in "${explicit_packages[@]}"; do
# pacman -Qi "$package" | grep -q 'Installation Reason *: *Explicitly installed' || \
# sudo pacman -D --asexplicit "$package" >/dev/null 2>&1
#done
#for package in "${all_packages[@]}"; do
# [[ -n "${dependencies[$package]}" ]] && \
# pacman -Qi "$package" | grep -q 'Installation Reason *: *Installed as a dependency' || \
# sudo pacman -D --asdeps "$package" >/dev/null 2>&1
#done
# Final report
explicit_count=$(printf "%s\n" "${explicit_packages[@]}" | wc -l)
dependency_count=$(comm -12 <(printf "%s\n" "${all_packages[@]}" | sort) <(printf "%s\n" "${!dependencies[@]}" | sort) | wc -l)
total_count=${#all_packages[@]}
echo "Pacman database normalized."
echo "Explicit: $explicit_count"
echo "Dependencies: $dependency_count"
echo "Total packages: $total_count"
if orphan_packages=$(pacman -Qqdt >/dev/null 2>&1); [[ -n "$orphan_packages" ]]; then
echo "Orphan packages: $orphan_packages"
fi