Bug in apticron (or dpkg ?) and trying to work around with apt-mark
Hi,
(sorry, the following is getting lengthy)
although I never used it myself, I think I found a bug in apticron.
I am using a snippet from apticron in a custom script to create a list of
upgradable packages and noticed that sometimes the number of packages
reported by apticron's internal logic differs from the number of
packages a subsequent call to "apt-get dist-upgrade" actually wants
to install.
This seems to affect packages which dpkg reports with appended architecture
(i.e. as in libfoo:amd64) whereas apt-get reports them without
(i.e. just libfoo).
I inserted the apticron code snippet I use below:
##############################################################
/usr/bin/apt-get -qq update || true
PKGNAMES=`/usr/bin/apt-get -q -y --ignore-hold --allow-unauthenticated -s dist-upgrade | \
/bin/grep ^Inst | /usr/bin/cut -d\ -f2 | /usr/bin/sort`
APTITUDE_HOLDS=`grep "^State: 2" -B 3 /var/lib/aptitude/pkgstates 2>/dev/null |grep "^Package: .*$" |cut -d" " -f 2`
DSELECT_HOLDS=`dpkg --get-selections |grep "hold$" |cut -f1`
if [ "$NOTIFY_HOLDS" = "0" ]; then
for p in $APTITUDE_HOLDS; do
PKGNAMES=`echo $PKGNAMES |sed "s/\(^\| \)$p\( \|$\)/ /g;s/^ //g"`
done
for p in $DSELECT_HOLDS; do
PKGNAMES=`echo $PKGNAMES |sed "s/\(^\| \)$p\( \|$\)/ /g;s/^ //g"`
done
fi
if [ "$NOTIFY_NEW" = "0" ]; then
for p in $PKGNAMES; do
if [ -z "`dpkg -s $p 2>/dev/null| grep '^Status: install ok installed'`" ] ; then
PKGNAMES=`echo $PKGNAMES |sed "s/\(^\| \)$p\( \|$\)/ /g;s/^ //g"`
fi
done
fi
NUM_PACKAGES=`echo $PKGNAMES |wc -w`
##############################################################
When I looked closer at what's happening I found that the calls to dpkg
DSELECT_HOLDS=`dpkg --get-selections |grep "hold$" |cut -f1`
and
`dpkg -s $p 2>/dev/null| grep '^Status: install ok installed'`
are the ones that generate the confusing results, and after some digging I
thought that replacing these with calls to apt-mark might resolve this.
The first one seems easy enough, replacing the original with
DSELECT_HOLDS=`apt-mark showholds`
reports the packages the same as apt-get does, for example on my own box:
$ dpkg --get-selections |grep "hold$" |cut -f1
hplip
hplip-data
hplip-gui
libhpmud0:amd64
libsane-hpaio:amd64
printer-driver-hpcups
$ apt-mark showholds
hplip
hplip-data
hplip-gui
libhpmud0
libsane-hpaio
printer-driver-hpcups
The second one gave me more headaches (especially since you may consider
me functional illiterate when it comes to shell programming :) .
Finally I came up with this (I am afraid somewhat clumsy) code:
if [ "$NOTIFY_NEW" = "0" ]; then
INSTALLED="`apt-mark showmanual` `apt-mark showauto`"
for p in $PKGNAMES; do
i="0"
for w in $INSTALLED; do
if [ $w = $p ]; then
i="1"
break
fi
done
if [ "$i" = "0" ]; then
PKGNAMES=`echo $PKGNAMES |sed "s/\(^\| \)$p\( \|$\)/ /g;s/^ //g"`
fi
done
fi
This *seems* to work, however I am not 100% sure that combining the output
of "apt-mark showmanual" and "apt-mark showauto" will really create a
list of all the installed packages and I feel that there might be
a better way of checking if the upgrade candidates are present in
the list of installed packages.
So finally here are my two questions, first can anyone confirm this
erroneous behavior of apticron (if yes, I think I might file a bug report),
and second does someone have a deeper insight into apt-mark's behavior
and maybe have an idea how to improve the check if the reported upgrade
candidates are actually installed?
Regards and TIA
Michael
.-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-.
Computers make excellent and efficient servants, but I have no wish to
serve under them. Captain, a starship also runs on loyalty to one
man. And nothing can replace it or him.
-- Spock, "The Ultimate Computer", stardate 4729.4
Reply to: