Skip to content

Instantly share code, notes, and snippets.

@don-coleman
Created February 22, 2021 09:46
Show Gist options
  • Save don-coleman/2218210aec58986acc80467f9a15d42b to your computer and use it in GitHub Desktop.
Save don-coleman/2218210aec58986acc80467f9a15d42b to your computer and use it in GitHub Desktop.
List all user-installed packages on OpenWrt - requires bash, and produces a more minimal list then other similar scripts.
#! /bin/bash
#
# We use bash associative arrays indexed by the package name.
#
opkg status \* | {
declare -A packages
declare -A packages_depends
declare -A packages_skip
declare -A packages_time
while read -r line; do
case "$line" in
"Package: "* )
name="${line:9}"
packages["$name"]="$name"
;;
"Depends: "* )
[ ! -v name ] && continue
# strip the leading label
line="${line:9}"
# strip version specs
line="${line//(=*)/ }"
# strip trailing commas
line="${line//,\ /\ }"
#echo packages_depends["${name}"]="$line"
packages_depends["${name}"]="$line"
;;
"Installed-Time: "* )
[ ! -v name ] && continue
time="${line:16}"
if [ ! -v OLDEST_TIME ] || [ "$time" -lt "$OLDEST_TIME" ]; then
OLDEST_TIME="$time"
fi
packages_time["${name}"]="${line:16}"
;;
"Auto-Installed: yes" )
[ ! -v name ] && continue
packages_skip["${name}"]=1
;;
"" ) # Empty line delinenates individual package blocks
unset name
;;
esac
done
# pass over all the packages with dependancies, and mark the packages they
# depend on to be skipped (since they are an implied install).
for name in "${!packages_depends[@]}"
do
# as package names can have shell special characters in them,
# roll our own list processing, paying attention only to spaces.
depend_list="${packages_depends["$name"]}"
# take each item upto the next space (skipping all leading spaces)
while [[ $depend_list =~ ([^[:space:]]+)(.*) ]]; do
# mark this dependancy to be skipped.
packages_skip["${BASH_REMATCH[1]}"]=1
# update list
depend_list="${BASH_REMATCH[2]}";
done
done
#echo "${!packages[@]}"
# now print the name of all the "not skipped" packages which were not
# installed at the very beginning.
for name in "${!packages[@]}"
do
[ ! -v packages_skip["${name}"] ] && [ "${packages_time["${name}"]}" -gt "${OLDEST_TIME}" ] && echo "${name}"
done | sort
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment