changing timezone with dpkg-reconfigure tzdata and debconf-set-selections
Simplest way that I know of is:
echo "Europe/Zurich" > /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
I just found out that with Debian Stretch (9) you need to also change /etc/localtime, thus something like:
ln -fs /usr/share/zoneinfo/`cat /etc/timezone` /etc/localtime
is needed. To amend andrekeller's answer you need:
echo "Europe/Zurich" > /etc/timezone
ln -fs /usr/share/zoneinfo/`cat /etc/timezone` /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
For using debconf, before calling dpkg-reconfigure, you need to also remove /etc/localtime
and /etc/timezone
. Also beware of possible extra space (as in your question!) which are not benign.
So "debconf way" that works (in Debian Stretch) would be:
echo "tzdata tzdata/Areas select Europe" | debconf-set-selections
echo "tzdata tzdata/Zones/Europe select Madrid" | debconf-set-selections
rm -f /etc/localtime /etc/timezone
dpkg-reconfigure -f noninteractive tzdata
The reason is that tzdata config script tries to be smart, and if it was ever configured before or user has manually meddled with timezones, will behave differently.
EXTRA
To debug similar problem yourself, you would first do:
export DEBCONF_DEBUG=developer
which would provide following info:
# dpkg-reconfigure -f noninteractive tzdata
debconf (developer): starting /var/lib/dpkg/info/tzdata.config reconfigure 2018e-0+deb9u1
debconf (developer): <-- VERSION 2.0
debconf (developer): --> 0 2.0
debconf (developer): <-- CAPB backup
debconf (developer): --> 0 multiselect escape
debconf (developer): <-- SET tzdata/Areas Etc
debconf (developer): --> 0 value set
debconf (developer): <-- SET tzdata/Zones/Etc UTC
debconf (developer): --> 0 value set
debconf (developer): <-- INPUT high tzdata/Areas
debconf (developer): --> 30 question skipped
debconf (developer): <-- GO
debconf (developer): --> 0 ok
debconf (developer): <-- GET tzdata/Areas
debconf (developer): --> 0 Etc
debconf (developer): <-- INPUT high tzdata/Zones/Etc
debconf (developer): --> 30 question skipped
debconf (developer): <-- GO
debconf (developer): --> 0 ok
debconf (developer): starting /var/lib/dpkg/info/tzdata.postinst configure 2018e-0+deb9u1
debconf (developer): <-- VERSION 2.0
debconf (developer): --> 0 2.0
debconf (developer): <-- GET tzdata/Areas
debconf (developer): --> 0 Etc
debconf (developer): <-- GET tzdata/Zones/Etc
debconf (developer): --> 0 UTC
debconf (developer): <-- STOP
which would show you that it forcefully SETs the values before asking the user for them (thus overwriting values you set with debconf-set-selections
).
Then you would change shebang in /var/lib/dpkg/info/tzdata.config
from #!/bin/sh
to #!/bin/sh -x
, and follow the program flow, where you would see that it does:
+ [ -L /etc/localtime ]
+ readlink /etc/localtime
+ TIMEZONE=/usr/share/zoneinfo/Etc/UTC
looking at /var/lib/dpkg/info/tzdata.config
you will find this:
# If /etc/localtime is a link, update /etc/timezone
if [ -L /etc/localtime ] ; then
TIMEZONE="$(readlink /etc/localtime)"
which explains why @fiction answer works. Also looking in the script more, you would find that @andrekeller answer also works in newer Debian versions if you remove '/etc/localtime'.
Hopefully this debugging help will help you when next version of Debian makes the script even smarter and existing answers became invalid too. More info on debugging debconf can be found in debconf-devel(7)