6

I have a Linux machine that only has very minimal cmds available on it, for example the /bin looks like this:

/bin# ls
ash            chattr         clockdiff      dd             dumpkmap       fdflush        gunzip         linux32        ls             mktemp         mt             pidof          printenv       rmdir          setserial      su             tracepath      umount         watch
busybox        chgrp          cp             df             echo           fgrep          gzip           linux64        lsattr         more           mv             ping           ps             run-parts      sh             sync           tracepath6     uname          zcat
cat            chmod          cpio           dmesg          egrep          getopt         hostname       ln             mkdir          mount          netstat        ping6          pwd            sed            sleep          tar            traceroute6    usleep
catv           chown          date           dnsdomainname  false          grep           kill           login          mknod          mountpoint     nice           pipe_progress  rm             setarch        stty           touch          true           vi

Also, it doesn't have /usr/share/zoneinfo dir.

So how can I set a time zone on it with these cmds? I also need to sync the time zone and date on it remotely from another host.

I tried TZ env variable, but it doesn't work, e.g:

root@xxx:/bin# date
Wed Aug 31 12:02:41 UTC 2023
root@xxx:/bin# TZ=America/New_York date
Thu Aug 31 12:03:50 America 2023
root@xxx:/bin# date
Thu Aug 31 12:04:58 UTC 2023

Notice that the time doesn't change when TZ is set.

Henry
  • 205

2 Answers2

13

If you don’t have timezone files, you can still specify the timezone by describing it in the TZ variable (see man tzset for details).

The minimal form is the timezone name followed by the offset from the timezone to UTC; thus

TZ=CEST-2

for central European summer time or

TZ=EDT4

for Eastern daylight time.

Transitions between different time offset (winter/summer, daylight savings etc.) can be described by specifying the two offsets and the dates at which they change; man tzset gives the following example for New Zealand:

TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"

When you do have timezone files, TZ is supposed to start with a colon to indicate their use:

TZ=:America/New_York
Stephen Kitt
  • 434,908
  • 1
    Thank you, in my case, timezone name followed by the offset works but it doesn't persist? The 2nd time I use date it goes back to its original time. – Henry Aug 31 '23 at 12:58
  • 10
    Yes, it’s a shell variable like any other; TZ=EDT4 date only sets it for that invocation of date. If you want it to persist, you need to export it (which will set it for all children of the current shell process), and if you want it more broadly you need to set it in a startup script. – Stephen Kitt Aug 31 '23 at 13:01
  • 1
    This works but this should come with a health warning. Others have expressed it better than me. Hard coding a time zone this way is so riddled with danger that if you can possibly find a solution involving the mainline /usr/share/zoneinfo files then you should use that instead. – Philip Couling Sep 01 '23 at 16:16
5

If you can transfer files to it, then you can copy the required timezone definition from your local system's /usr/share/zoneinfo to /etc/localtime on the limited system. Testing this out in an Alpine container:

% docker run --rm -it alpine date
Fri Sep  1 07:15:13 UTC 2023
% docker run --rm -it -v /usr/share/zoneinfo/Asia/Calcutta:/etc/localtime alpine date
Fri Sep  1 12:45:17 IST 2023

Your list of commands includes ash and busybox. IIRC the common versions of the Almquist shell on Linux are dash and busybox sh, and its possible that like with Alpine, most of your commands are just symlinks to busybox. By using Alpine to test, I think it'll be representative of your system.

If you have root SSH access, but it's constrained somehow to disallow SFTP and scp, you can try:

ssh limited-server 'cat > /etc/localtime' < /usr/share/zoneinfo/Some/Place
muru
  • 72,889
  • This is exactly what a company I work for is doing with their embedded (similar to raspberry-pi) devices; copy the correct timezone file to /etc/localtime when customizing a device to a particular customer. No need to dump the whole zoneinfo db on the device if you only ever need one single file. – Guntram Blohm Sep 01 '23 at 11:43
  • I think it would be better to use your local system to fetch (not be the source of) the most up to date files from IANA and use those (described here). It ensures you get the latest db irrespective of your own workstation and has more reproducible results for a CI pipeline etc. – Philip Couling Sep 02 '23 at 03:16
  • I chose this solution because the other answer needs me to add time offset between zones manually, it works but does not work very well when that needs to be changed from time to time, and it loses the changes when a new remote terminal opens in my case. – Henry Sep 05 '23 at 15:35