lostwebsite.net blog

Annex to the Lost Website

Interesting Bash snippet

with 3 comments

This little Bash snippets scans the Debian dpkg database for packages whose configurations files have been modified.

This only touches configurations files which are packaged and made known to dpkg. Some package manually handle their configuration file in maintainer scripts. A good example of that is /etc/network/interfaces which is an important configuration file but not automatically handled by dpkg.

This is as useful as you want to make it. I use it to track changes I’ve done which could end up with a conflict during a package upgrade. If you want a more thorough tracking of configuration changes, use something like etckeeper.

Notice I took some care to use more Bash’isms, to optimize the script. I was able to optimize by just a few percents. The bulk of the time must spent calculating MD5 sums.

#!/bin/bash

for pkg in /var/lib/dpkg/info/*.conffiles; do
    p1=${pkg#/var/lib/dpkg/info/}
    p=${p1%%.conffiles}
    IFS=$'n'
    for cfsum in $(dpkg-query -W -f='${Conffiles}' $p); do
        IFS=' '
        c=($(eval "echo $cfsum"))
        if [ -r ${c[0]} ]; then
            sum=${c[1]}
            cur_sum=($(eval "md5sum ${c[0]}"))
            if [ $sum != ${cur_sum[0]} ]; then
                echo "$p: ${c[0]}"
            fi
        else
            echo "Can't access file: ${c[0]}." > /dev/stderr
        fi
    done
done

This will output something like this:

$ ./check_changed
bash: /etc/bash.bashrc
console-tools: /etc/console-tools/config
libldap2: /etc/ldap/ldap.conf
ntp: /etc/ntp.conf
...

Written by fdgonthier

February 18, 2009 at 12:01 pm

Posted in Debian, Linux, Misc

Tagged with , , , ,

3 Responses

Subscribe to comments with RSS.

  1. The first two lines could be merged into p=$(basename ${x%.*}), where ${x%.*} strips the shortest match from the right.

    Steven Pigeon

    February 18, 2009 at 3:03 pm

  2. I did not want to call basename because its not internal to Bash.

    I could simply write the 2 first line as:

    p=$(basename $pkg .conffiles)

    But ‘basename’ is an external process and probably an tiny bit slower than the 2 lines. I admit I’m splitting hairs but my goal when optimizing was to limit the external calls.

    fdgonthier

    February 18, 2009 at 3:08 pm

  3. That’s an interesting one, I didn’t know basename would strip a suffix, if supplied.

    Steven Pigeon

    February 18, 2009 at 3:14 pm


Leave a Reply