Skip to content

Instantly share code, notes, and snippets.

@mtekman
Last active December 15, 2021 23:24
Show Gist options
  • Save mtekman/9769fa3eb28dd0dbdd1e8ce802157e95 to your computer and use it in GitHub Desktop.
Save mtekman/9769fa3eb28dd0dbdd1e8ce802157e95 to your computer and use it in GitHub Desktop.
Determining the least used packages installed on your system
#!/usr/bin/bash
function pacman-last-used {
trap 'updateTermWidth' WINCH
storage_dir=${HOME}/.config/pacman-last
mkdir -p "$storage_dir"
unsorted=$storage_dir/"packages.1.exec_bins.log"
sorted=$storage_dir/"packages.2.exec_bins.sorted"
sorted_packs=$(mktemp) #"3.packages.sorted"
sorted_packs_flat=$storage_dir/"packages.3.first_last_usage"
sorted_packs_last=$storage_dir/"packages.4.last_usage_grouped_by_date"
cmd_package_ownership=""
cmd_package_name=""
function setPacmanFuncs {
## Checks for pacman and sets ownership functions
if [ "$(which pacman)" ]; then
cmd_package_ownership='pacman -Qo';
cmd_package_name='sed -r "s|^.+is owned by (.*)\s.+|\1|"';
else
echo "pacman could not be found" && exit 255;
fi
}
function updateTermWidth {
## Global term width, updated on SIGWINCH
width=$(stty size | cut -d" " -f 2)
}
function calc_packages {
## Gather and group last access times for all packages.
if [ -e "$unsorted" ] && [ -s "$unsorted" ]; then
echo -n " [Info] $unsorted already exists. Overwrite [y/n]? ";
read -r ans;
[ "$ans" != "y" ] && echo " [Info] Using existing." && return 0
fi
# Otherwise proceed
echo "" > "$unsorted"
echo " [Info] Checking:"
for dir in ${PATH//:/ };
do
! [ -e "$dir" ] && echo "[INFO] $dir does not exist, skipping" && continue
local num;
local count;
files="$(find "$dir" -maxdepth 1 -type f)"
num=$(echo "$files" | wc -l)
((count=0))
echo " $dir"
for bin in $files; do
((count++))
local full_path last_used owned_by line out
full_path=$bin ##$dir/$bin
last_used=$(stat -c %x "$full_path")
owned_by=$(eval "$cmd_package_ownership" "$full_path" 2>&1 | eval "$cmd_package_name")
[ "$(echo "$owned_by" | grep error)" != "" ] && owned_by="ERROR"
out="${last_used}\t${full_path}\t${owned_by}"
echo -e "$out" >> "$unsorted"
line=$( printf " (%4d / %4d) %30s -- %s" "$count" "$num" "$owned_by" "$full_path" )
printf "\r%-${width}s" "$line"
done
done
}
function sanityCheck {
file="$1"
message="$2"
if [[ -n "$file" ]]; then
! [ -e "$file" ] && echo "[Error] Cannot find $file. Terminating." && exit 255
fi
[ "$message" != "" ] && echo "$message"
}
setPacmanFuncs
echo ""
sanityCheck "" " - 1. Gathering info on all bins in PATH"
calc_packages
sanityCheck "$unsorted" " - 2. Sorting bins by package ownership and date"
awk '{print $1"\t"$4"\t"$5}' "$unsorted" | sort -k3 -k1n > "$sorted"
sanityCheck "$sorted" " - 3. Sorting packages by first and last usage"
awk -F'\t' '{print $3"\t"$1}' "$sorted" | uniq > "$sorted_packs"
# Flatten lines of adjacent packages
sanityCheck "$sorted_packs" ""
awk -F'\t' 's != $1 || NR ==1{s=$1;if(p){print p};p=$0;next}{sub($1,"",$0);p=p""$0;}END{print p}' "$sorted_packs"\
| awk -F"\t" '{print $1"\t"$2"\t"$NF}' > "$sorted_packs_flat"
sanityCheck "$sorted_packs_flat" " - 4. Grouping packages by date (last usage)"
sort -k3 "$sorted_packs_flat"\
| awk -F'\t' '{print $3"\t"$1}'\
| awk -F'\t' 's != $1 || NR ==1{s=$1;if(p){print p};p=$0;next}{sub($1,"",$1);p=p""$0;}END{print p}'\
> "$sorted_packs_last"
echo ""
echo " [Info] Files written:
-> $unsorted
-> $sorted
-> $sorted_packs_flat
-> $sorted_packs_last"
echo ""
}
pacman-last-used
@mtekman
Copy link
Author

mtekman commented Aug 26, 2020

Hmm I see. From the stat man page I don't see any real way to access ctime or another time parameter that is more permanent against package updates.

I guess this script is maybe more for highlighting packages that have both not been updated in a while and not been accessed in a while. It could be a good measure for rooting out stagnant packages perhaps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment