Re: looking for packages versions of running daemons
Cameron Hutchison <lists@xdna.net> writes:
>Ok. Here's version 2. Fixes are:
One more iteration before I go to bed.
Version 2 was the quickly knocked together script that looks ugly and
hard to read, but is nice and compact. Maybe "nice" isn't the right
word.
Version 3 (below) is "properly" written, in a functional style. It's much
longer, but much easier to read. The main() function is very simple,
as is each individual function. It's written in such a way that you
can add extra filters if you want to extend it to get extra information
(like the -v bit you asked about).
If you dont want the result pretty-printed, just remove the
"| map_lines pretty_print" in main.
The only fix is to ignore errors from xargs (in get_pid_from_exe) which
I noticed coming out on a faster machine.
It runs under bash for the "local" keyword, but I think that should also
work under /bin/sh on Debian. It probably needs gnu xargs for -0 (gnu
xargs is standard on Debian, but busybox xargs may be different).
#!/bin/bash
main()
{
ports_and_pids \
| map_lines add_pkg_info \
| map_lines pretty_print
}
ports_and_pids()
{
netstat -lntup \
| awk '/^tcp/ { print $4"/"$1, $7 } /^udp/ { print $4"/"$1, $6 }' \
| sed -n 's|^[^ ]*:\([^ ]*\) \([0-9]*\)/.*|\1 \2|p' \
| sort -nu
}
add_pkg_info()
{
local port=$1 pid=$2 bin pkg version newer
bin=$(get_exe_from_pid $pid) || return
pkg=$(get_pkg $bin) && {
version=$(get_installed_version "$pkg")
newer=$(get_latest_version "$pkg")
[ "$newer" != "$version" ] || newer=""
}
echo $port $pid $bin $pkg $version $newer
}
pretty_print()
{
[ -n "$1" ] && [ -n "$3" ] || return
echo "$3 on port $1 ${4+from package $4}" \
"${5:+(version $5${6:+, $6 available})}"
}
get_exe_from_pid()
{
[ -d /proc/$1 ] || return
local bin=$(
xargs -n 1 -0 echo < /proc/$1/cmdline 2>/dev/null \
| awk '{print $1 ; exit}'
)
[ -x "$bin" ] || bin=$(readlink /proc/$1/exe | sed 's/ (deleted)//')
echo $bin
}
get_pkg()
{
local pkg=$(dpkg -S "$1" 2>/dev/null | cut -d: -f1)
[ -n "$pkg" ] || return
echo "$pkg"
}
get_installed_version()
{
dpkg-query -W --showformat='${Version}' "$1"
}
get_latest_version()
{
apt-cache show -a $pkg \
| awk '/^Version:/ {print $2}' \
| foldl_lines latest_version ""
}
latest_version()
{
dpkg --compare-versions "$1" gt "$2" && echo "$1" || echo "$2"
}
# map_lines func
# evaluate "func" for each line of input
map_lines()
{
while read line ; do
eval $1 $line
done
}
# foldl_lines func lhs
# evaluate (func (func (func lhs line1) line2) line3) ... for lines of input
foldl_lines()
{
func=$1
lhs="$2"
while read line ; do
lhs=$(eval $func "$lhs" "$line")
done
echo $lhs
}
Reply to: