17

I want to set up a script that automatically changes the timezone on a machine (running ubuntu 11.10) and also sets the right values to the debconf database. I've tried the following, but it does not work (at the end, the current timezone remains unchanged, and if I run manually the dpkg-reconfigure tzdata command, the selected values are indeed the old ones):

#!/bin/sh -e
echo "tzdata    tzdata/Areas    select  Europe" | debconf-set-selections
echo "tzdata    tzdata/Zones/Europe select  Madrid" | debconf-set-selections
echo "tzdata    tzdata/Zones/America    select  " | debconf-set-selections
dpkg-reconfigure -f noninteractive tzdata

So, by now, I'm doing it messing with the files /etc/localtime and /etc/timezone directly, but I'd rather prefer the dpkg-reconfigure and debconf way.

26

Simplest way that I know of is:

echo "Europe/Zurich" > /etc/timezone 
dpkg-reconfigure -f noninteractive tzdata
  • wbat do the parameters to dpkg-reconfigure mean? – serengeti12 Jan 11 '13 at 0:02
  • 5
    Be aware that running processes may not pick up the change without a restart. Eg log timestamps from server daemons are likely to be wrong until you restart the daemons. – mc0e Mar 4 '14 at 15:25
6

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
  • Saved my day! Other solutions do not work in Debian 9 – Brandon Sep 29 '17 at 18:28
  • 2
    Actually only linking etc/localtime is needed, as calling dpkg-reconfigure will set /etc/timezone correctly – Daniel Dinnyes Oct 31 '17 at 22:54
  • @DanielDinnyes or alternatively you can replace that ungainly ln -fs .... line with simple rm -f /etc/localtime, and it will still work (and debconf would recreate /etc/localtime with correct values); see my answer for details. – Matija Nalis Sep 27 '18 at 12:31
4

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/shto #!/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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.