...
分类: LINUX
2007-12-06 22:44:12
Linux 上的系统时间非常重要。在前面已经看到,cron 和 anacron 设施根据时间执行作业,所以它们需要精确的时间。前一节中讨论的大多数备份和恢复工具,以及 make
等开发工具,也依赖于可靠的时间。1980 年以后生产的大多数计算机都包含某种时钟机制,1984 年以后生产的大多数计算机通常有持久的时钟机制,即使计算机关闭了,仍然可以维护时间。
如果以图形化方式安装 Linux 系统,那么可能根据自己的需要设置了时钟和时区。还可以使用 Network Time Protocol(NTP)设置时钟,可以使用 Coordinated Universal Time(UTC)维护系统时钟。如果用 Fedora、Red Hat 或相似系统上的图形工具设置过时钟,您可能见过图 3 这样的对话框。
令人吃惊的是,实际上无法用这个对话框设置时钟。在本节中,学习本地时钟和 NTP 之间的差异以及如何设置系统时间。
无论您生活在 New York、Budapest、Nakhodka、Ulan Bator、Bangkok 还是 Canberra,大多数 Linux 时间的计算都与 Coordinated Universal Time(UTC)相关。如果使用专有的 Linux 系统,往往会将硬件时钟设置为 UTC;但是,如果还要引导另一个操作系统(比如 Windows),那么可能需要将硬件时钟设置为本地时间。这一般不是问题,因为 Linux 会负责处理,但是 Linux 内部有两种跟踪时区的方法;如果它们不一致,在 FAT 文件系统上可能会产生一些奇怪的时间戳和其他现象。清单 55 演示如何使用 date
命令显示当前日期和时间。显示的总是本地时间,即使硬件时钟设置为 UTC 时间。
[root@lyrebird ~]# date;date -u Mon Jul 9 22:40:01 EDT 2007 |
date
命令支持许多输出格式,在 清单 28 中已经看到过其中一些格式。如果想进一步了解各种日期格式,请参考 date
的手册页。
如果需要设置日期,那么可以提供日期和时间参数。出于历史原因,所需的格式对于美国人来说有点儿古怪,对于其他地区的人甚至更奇怪。必须至少按照 MMDDhhmm 格式指定月、日、小时和分钟,还可以加上两位或四位的年份(CCYY 或 YY)以及可选的点号(.),后面加上两位的秒数。清单 56 设置了系统日期。
[root@lyrebird ~]# date; date 0709221407;date Mon Jul 9 23:12:37 EDT 2007 Mon Jul 9 22:14:00 EDT 2007 Mon Jul 9 22:14:00 EDT 2007 |
|
Linux 系统和大多数其他现代操作系统实际上有两个时钟。第一个时钟是硬件时钟,有时称为 Real Time Clock(RTC)或 BIOS 时钟,这个时钟常常与石英晶体的振荡频率相关,它的误差只有每天几秒。它会受到环境温度等因素的影响。第二个时钟是内部软件时钟,这由计数系统中断控制。它会受到系统高负载和中断延迟的影响。系统通常会在启动时读取硬件时钟,在此之后使用软件时钟。date
命令设置软件时钟,而不是硬件时钟。
如果使用 Network Time Protocol(NTP),那么可以在安装系统时设置硬件时钟,然后就不用再管它了。如果不使用 NTP,本节将讲解如何显示和设置硬件时钟时间。
可以使用 hwclock
命令显示硬件时钟的当前值。清单 57 同时显示系统时钟和硬件时钟的当前值。
[root@lyrebird ~]# date;hwclock Mon Jul 9 22:16:11 EDT 2007 Mon 09 Jul 2007 11:14:49 PM EDT -0.071616 seconds |
注意,这两个值有差异。可以使用 hwclock
的 -w
或 --systohc
选项让硬件时钟与系统时钟同步。可以使用 -s
或 --hctosys
选项让系统时钟与硬件时钟同步,见清单 58。
[root@lyrebird ~]# date;hwclock;hwclock -s;date Mon Jul 9 22:20:23 EDT 2007 Mon 09 Jul 2007 11:19:01 PM EDT -0.414881 seconds Mon Jul 9 23:19:02 EDT 2007 |
可以指定 --utc
或 --localtime
选项,让系统时钟与 UTC 或本地时间同步。如果没有指定值,就从 /etc/adjtime 的第三行获得值。
Linux 内核有一种模式,它每 11 分钟将系统时间复制到硬件时钟。默认情况下这个模式是关闭的,但是 NTP 会打开它。如果以老式方式设置时间,比如 hwclock --hctosys
,就会关闭这个模式,所以如果使用 NTP,最好让 NTP 自己负责,不要手工设置时间。在 adjtimex
的手册页中介绍了如何检查时钟是否每 11 分钟更新。可能需要安装 adjtimex 包,因为默认情况下可能没有安装这个包。
hwclock
命令会记录对硬件时钟的修改,以便补偿时钟频率的误差。必需的数据点保存在 /etc/adjtime 中,这是一个 ASCII 文件。如果不使用 Network Time Protocol,那么可以使用 adjtimex
命令补偿时钟漂移。如果使用 NTP,NTP 大约每 11 分钟调整一次硬件时钟。除了显示硬件时钟是本地时间还是 UTC 时间之外,/etc/adjtime 中的第一个值还显示每天的硬件时钟漂移量(以秒为单位)。清单 59 给出两个示例。
[root@lyrebird ~]# cat /etc/adjtime 0.000990 1184019960 0.000000 1184019960 LOCAL root@pinguino:~# cat /etc/adjtime -0.003247 1182889954 0.000000 1182889954 LOCAL |
注意,这两个系统都按照本地时间记录硬件时钟,但是时钟漂移不一样 — 在 lyrebird 上是 0.000990,在 pinguino 上是 -0.003247。
|
时区表示本地时间与 UTC 相差多少。可以配置关于时区的信息,这些信息保存在 /usr/share/zoneinfo 中。/tec/localtime 以前常常是指向这个目录树中一个时区文件的链接,例如 /usr/share/zoneinfo/Eire 或 /usr/share/zoneinfo/Australia/Hobart。在现代系统上,它往往是适当时区数据文件的副本,因为在引导过程的早期需要本地时区信息,但是这时候 /usr/share 文件系统可能还没有挂装。
同样,另一个文件 /etc/timezone 以前常常是 /etc/default/init 的链接,它用来设置时区环境变量 TZ 和几个与地区相关的环境变量。您的系统上可能有这个文件,也可能没有。如果有这个文件,它可能只包含当前时区的名称。还可能在 /etc/sysconfig/clock 中找到时区信息。清单 60 显示 Ubuntu 7.04 和 Fedora 7 系统上的这些文件。
root@pinguino:~# cat /etc/timezone America/New_York [root@lyrebird ~]# cat /etc/sysconfig/clock # The ZONE parameter is only evaluated by system-config-date. # The timezone of the system is defined by the contents of /etc/localtime. ZONE="America/New York" UTC=false ARC=false |
Debian 和 Ubuntu 等系统用 tzconfig
命令设置时区。Fedora 等其他系统使用 system-config-date
设置时区并指出时钟是否使用 UTC。清单 61 使用 tzconfig
命令显示当前时区。
root@pinguino:~# tzconfig Your current time zone is set to America/New_York Do you want to change that? [n]: Your time zone will not be changed |
|
Network Time Protocol(NTP)是一种通过网络对计算机时钟进行同步的协议。通常是与 UTC 同步。
NTP 3 是一个互联网标准草案(RFC 1305)。当前正在开发的版本(NTP 4)是一个重要的修订版,当前还没有完成。RFC 4330 描述了 Simple NTP(SNTP)4。
时间同步是通过向时间服务器(time server) 发送消息来完成的。对于返回的时间,要用网络往返延迟时间的一半进行调整。因此,时间的精度依赖于网络延迟,以及两个方向上的延迟是否大致相同。到时间服务器的路径越短,时间的精度就可能越高。更详细的信息参见 参考资料。
互联网上的计算机非常多,所以时间服务器组织成一个层(stratum)。很少的几台 1 级服务器通过原子钟这样的时间源维护非常精确的时间。数量较多的 2 级服务器从 1 级服务器获得时间,并向数量更多的 3 级服务器提供时间,以此类推。为了减轻时间服务器的负载,有许多志愿者通过 pool.ntp.org 提供时间服务(参见 参考资料 中的链接)。循环式 DNS 服务器将 NTP 服务器请求分布在可用服务器池中,从而实现 NTP 负载平衡。
如果使用图形界面,那么可以使用与图 4 相似的对话框设置 NTP 时间服务器。这个系统使用 NTP 自动更新时间,所以图 3 中的对话框不允许修改日期和时间。
NTP 配置信息保存在 /etc/ntp.conf 中,所以也可以编辑这个文件,然后保存文件并重新启动 ntpd 守护进程。清单 62 给出一个 /etc/ntp.conf 文件示例,它使用图 4 中的时间服务器。
[root@lyrebird ~]# cat /etc/ntp.conf # Permit time synchronization with our time source, but do not # permit the source to query or modify the service on this system. restrict default kod nomodify notrap nopeer noquery # Permit all access over the loopback interface. This could # be tightened as well, but to do so would effect some of # the administrative functions. restrict 127.0.0.1 # Hosts on local network are less restricted. #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap # Use public servers from the pool.ntp.org project. # Please consider joining the pool (). #broadcast 192.168.1.255 key 42 # broadcast server #broadcastclient # broadcast client #broadcast 224.0.1.1 key 42 # multicast server #multicastclient 224.0.1.1 # multicast client #manycastserver 239.255.254.254 # manycast server #manycastclient 239.255.254.254 key 42 # manycast client # Undisciplined Local Clock. This is a fake driver intended for backup # and when no outside source of synchronized time is available. #server 127.127.1.0 # local clock #fudge 127.127.1.0 stratum 10 # Drift file. Put this in a directory which the daemon can write to. # No symbolic links allowed, either, since the daemon updates the file # by creating a temporary in the same directory and then rename()'ing # it to the file. driftfile /var/lib/ntp/drift # Key file containing the keys and key identifiers used when operating # with symmetric key cryptography. keys /etc/ntp/keys # Specify the key identifiers which are trusted. #trustedkey 4 8 42 # Specify the key identifier to use with the ntpdc utility. #requestkey 8 # Specify the key identifier to use with the ntpq utility. #controlkey 8 server 0.us.pool.ntp.org restrict 0.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery server 1.us.pool.ntp.org restrict 1.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery server 2.us.pool.ntp.org restrict 2.us.pool.ntp.org mask 255.255.255.255 nomodify notrap noquery |
如果要使用 pool.ntp.org 时间服务器,世界各地都有这些服务器。通过限制使用的服务器,常常可以获得更准确的时间;例如在这个示例中,使用 us.pool.ntp.org,因此只选择美国的服务器。关于 ntp.pool.org 项目的更多信息参阅 参考资料。
可以使用 ntpdate
命令按照 NTP 时间服务器设置系统时间,见清单 63。
[root@lyrebird ~]# ntpdate 0.us.pool.ntp.org 10 Jul 10:27:39 ntpdate[15308]: adjust time server 66.199.242.154 offset -0.007271 sec |
因为服务器采用循环模式,所以下一次运行这个命令时可能会看到另一个服务器。清单 64 显示在运行上面的 ntpdate
命令之后,对 0.us.ntp.pool.org 的前几个 DNS 响应。
[root@lyrebird ~]# dig 0.pool.ntp.org +noall +answer | head -n 5 0.pool.ntp.org. 1062 IN A 217.116.227.3 0.pool.ntp.org. 1062 IN A 24.215.0.24 0.pool.ntp.org. 1062 IN A 62.66.254.154 0.pool.ntp.org. 1062 IN A 76.168.30.201 0.pool.ntp.org. 1062 IN A 81.169.139.140 |
ntpdate
命令现在已经废弃了,因为使用 ntpq
命令和 -q
选项可以实现同样的功能,见清单 65。
[root@lyrebird ~]# ntpd -q ntpd: time slew -0.014406s |
注意,ntpd
命令使用来自 /etc/ntp.conf 或命令行上提供的配置文件的时间服务器信息。关于 ntpd
的更多信息参见手册页。还要注意,如果 ntpd 守护进程正在运行,那么 ntpd -q
会悄悄退出,并在 /var/log/messages 中记录一个失败消息。
另一个相关命令是 ntpq
命令,可以用它查询 NTP 守护进程。更多细节参见手册页。