2016-03-11
Why it's irritating when Ubuntu packages don't include their configuration files
I'll start with my tweets:
This is my angry face when Ubuntu openssh-server generates a fixed /etc/ssh/sshd_config on the fly in postinst vs making it a config file.
Ubuntu dovecot also does the 'generate static configuration files at install time' thing and now I want to set it on fire.
(Twitter has become my venue of choice for short rants.)
Both of these packages have the same bad idea, although their
mechanisms differ somewhat. Specifically, the installed and running
software has some configuration files (here /etc/ssh/sshd_config
and /etc/dovecot/conf.d/*
), but these files are not actually
packaged in the .deb
s; instead they are created at install time
when the package is installed from scratch.
(The behavior may be there in the Debian versions as well, but I don't run Debian so I can't easily check.)
Years ago I wrote about wishing to be able to retrieve the stock
version of some package file. At the time
I gave a recipe for doing this by hand on a Debian based system;
you apt-get download
the .deb
, use dpkg -x
to unpack it in a
temporary directory, and fish the file out. Naturally this only
works if the .deb
actually packages the file. If it does not,
you have two options. First, you can find, read, and probably
simulate by hand the process the .postinst
script uses to create
the file (the postinst script itself is likely in /var/lib/dpkg/info
).
Second, you have to install an uncustomized version of the package
somehow, either on a test machine or by purging and then reinstalling
the package (which is likely to be very disruptive if you have any
important local customizations).
This is what I call 'not helpful'. There are all sorts of reasons to want to retrieve the original version of a configuration file that you've altered (or merely may have altered). Even when this is possible, how to do it is package specific, which means that you need package specific knowledge or research. Ubuntu packaging should do better here.
(I don't expect things to ever change, though. I rather expect that this is inherited from Debian and Debian has some intricate reason of their own for doing it this way (and for different packages doing it differently). Debian sometimes makes me angry with their apparent love of robot logic, technical intricacies, and apparent inability to ever do something in a single unified way.)
I need to use getopts
sooner (and more often) in Bourne shell scripts
I have this flaw in my Bourne shell scripting; in shell scripts and shell scripts alone, I find it all too easy and tempting to reach for ad-hoc option processing when I add the first option to a script. Inevitably, handling the first option will look something like:
[...] SOMEVAR=0 if [ "$1" = "-L" ]; then SOMEVAR=1; shift fi [...]
When a second option shows up, it sometimes winds up getting wedged awkwardly into the same sort of code. Maybe the options conflict so they'll never get used together in practice, or I'll tell myself that I'll always remember the order, or some equally bad excuse.
Doing this is a mistake, and I need to accept that. Rather than ever
writing ad-hoc option processing code, I should be using getopts
in my scripts right from the start even in tiny little scripts. Even
using getopts
for a single option is not that much more code over the
simple version above, and it has better error handling. And of course,
adding more options is much simpler and works much better if I'm using
getopts
already.
(Probably I should just memorize and master a standard getopts
stanza so I can drop it into everything by reflex. But that's going
to take time, and also not reflexively reaching for the quick
solution for single options.)
I'm not entirely sure why I'm so reluctant in practice to use
getopts
, but for whatever reason it's not part of my shell landscape
most of the time. This is silly, as getopts
has existed for a
long time and is a Single Unix Specification standard.
As a practical matter it's long since been supported everywhere
that I'm ever going to run a shell script. I need to get with the times
and update my Bourne shell habits.
(This entry is brought to you by me updating some scripts today,
trying to add a second option to them in a terrible way, and then
telling myself that I should be doing this right and switching them
over to using getopts
. The resulting shell script code is both
better and shorter.)