I finally remembered this thread, here's a rewrite of the script I did a few weeks back and a couple notes.
The opkg whatdepends x
command computes the transitive closure of dependencies, so you get not just those packages that depend directly on x
, but those packages that depend on the packages that depend on the packages... You get the idea, try opkg whatdepends terminfo
for an example. As you've probably already guessed, this is phenomenally slow.
All of the information about packages is in /usr/lib/opkg/info/
, with the *.control
files being the most interesting. This is where opkg
subcommands look for any information about installed packages, and you can just ls
that directory and see what is installed.
Replacing whatdepends
with appropriate grep
+ awk
drops run time of the script from ~180+ seconds to ~5 seconds on my edge router (an apu2 x86), but it changes the dependency count reported on many of the non-top-level packages (i.e., those with zero dependencies), because it skips the transitivity search. If you can live with that, you can save some CPU cycles.
Also of note is that there is an alias-like (or maybe more symbolic-link-like?) thing that opkg
supports. You can see it with grep 'Provides:' /usr/lib/opkg/info/*.control
. It's easy to see it in action with the packages dnsmasq
and dnsmasq-full
, where the 'Provides:' field in both says (duh) dnsmasq
. The opkg
subcommands parse through these and make sure to do the right thing, whereas my script sometimes sticks in both the "real" package name and an alias for it in the output.
This manifests as some packages being reported as "top-level" even though they are not (for example, you'll see firewall4
reported as a top-level package, when in fact it "supplies" uci-firewall
, which has a bunch of dependents). So far, I've only seen firewall4
and tc-tiny
reported this way, and anyway these false positives won't break anything, they're just annoying.
Enough of my blah blah blah, here's the script.
#!/bin/sh
# vim: set expandtab softtabstop=4 shiftwidth=4:
#-------------------------------------------------------------------------------
log_all=false # Log everything, or just those with count == 0.
package_list=./installed-packages
rm -f $package_list
examined=0
for pkg in $(opkg list-installed | awk '{print $1}') ; do
examined=$((examined + 1))
printf '%5d - %-40s\r' "$examined" "$pkg"
#deps=$(opkg whatdepends "$pkg" | awk '/^\t/{printf $1" "}')
deps=$(
cd /usr/lib/opkg/info/ &&
grep -lE "Depends:.* ${pkg}([, ].*|)$" -- *.control | awk -F'\.control' '{printf $1" "}'
)
count=$(echo "$deps" | wc -w)
if $log_all || [ "$count" -eq 0 ] ; then
printf '%d\t%s\t%s\n' "$count" "$pkg" "$deps" >> $package_list
fi
done
n_logged=$(wc -l < $package_list)
printf 'Done, logged %d of %d entries\n' "$n_logged" "$examined"