本章说明
Linux系统如何keepstime,及需要做什么来避免发生问题。通常,你无须对
时间做什么,但理解它会更好。
& o+ Y. f5 b; o8 ~3 g 时区
; B' p" w& h: {7 E% [ 时间测量基于最规则的自然现象,如地球转动导致的昼夜更替。昼夜总时间是恒定的,但昼夜分别的长度是变化的。一个简单的常数是正午。
; I; c, i2 J" n+ O' k7 {7 q# `[color=#FFFFFF']
5 T9 R# X* ?2 Q0 l5 A' F
' F, g$ M, \' g9 J9 y3 U5 n! N
_0 E$ t! e9 I 正午是白天太阳在最高点的时间。由于地球是圆的,不同地方正午发生在不同的时间。这引出了本地时localtime的概念。
' ^( N; j1 k# ?0 b$ L0 t# Y
硬件时钟和
软件时钟
2 J# r( b- W/ w# M" c# ]8 k9 n
个人
计算机有一个
电池驱动的硬件时钟。电池保证始终在计算机没电的时候依然能工作。硬件始终能从BIOS设置屏或操作系 统的别的地方进行设置。
' v; d' _0 N3 s/ V$ C
[color=#FFFFFF']
; U4 ] k7 y% C4 x; E/ C* p9 n
- s1 H9 }4 o7 O1 s, ~4 X2 A Linux核心独立于硬件始终跟踪时间。启动时,Linux根据硬件时钟设置自己的时钟。此后,2个始终相互独立运行。因为查看硬件始终慢而复杂,因此Linux
管理自己的时钟。
4 f6 \0 w( `# s3 E& Z* k2 D
核心始终一直显示通用时间。这样,核心无须知道时区,高可靠的简单结果使更新时区
信息更简单。每个进程自己处理时区转换(使用时区包部分里的
标准工具)。
+ p- L4 {+ R3 B6 U
硬件始终可以是本地时间或通用时间。通常用通用时间更好,因为这样你无须在夏时制开始或结束时改变硬件时钟(UTCdoesnothaveDST)。不幸的是,有些PC
操作系统,包括MSDOS、
Windows、OS/2都假设硬件时钟是本地时间。Linux可处理2种方式,但如果硬件时钟显示本地时间,那么必须在夏时制开始或结束时(否则就不能显示本地时间)。
# ^6 l9 b5 x- N$ M/ {9 F0 o 显示和设置时钟
% R4 v, l. b. t: \; b% O9 h3 ` 在Debian系统中,系统时区由符号连接/etc/localtime决定。连接指向
描述本地时区的时区
数据文件。时区
数据文件存在/usr/lib/zoneinfo中。其他Linuxdistributions可能不同。
4 m" b* s3 n) }2 M$ s- C 用户可以用设置TZ
环境变量来改变他的私人时区。如果不设置,就假定是系统时区。TZ变量的语法在tzset(3)man页中说明。
/ P/ C7 X7 d0 C8 f" L; r1 y: ~
date命令显示当前日期和时间。例如:
5 ~8 i8 Q) N- k7 f+ z; d[color=#FFFFFF']
9 F( ^6 X' Z4 b6 G3 }+ G- U
: h) v. M) I" w5 i2 o* q4 O- f $date
* I3 Z0 x+ s& {8 ^8 j
SunJul1421:53:41EETDST1996
+ f# l" G2 `) e7 W" \9 N
$
& ~( ^" i$ d# D4 M7 Z1 b2 c ThattimeisSunday,14thofJuly,1996,atabouttenbeforetenattheevening,inthetimezonecalled``EETDST\\\'\\\'(whichmightbeEast EuropeanDaylightSavingsTime).date也可用于显示通用时间:
6 d7 F% b. }: p3 n6 |& c
$date-u
, y- z7 i# ~5 l0 d9 `0 t9 T
SunJul1418:53:42UTC1996
% v7 y L. ^& U4 D U
$
9 i; b' v/ Y% E: C; [- o% e* z
date也可用于设置核心的软件始终:
8 o' @% K4 T; h5 M S: {
#date07142157
/ ]2 v7 n6 c" S0 Q( c. N SunJul1421:57:00EETDST1996
( c6 p! r: d {+ P #date
% @# } Q/ k+ O SunJul1421:57:02EETDST1996
- V& B8 G$ Z; i8 h1 C #
0 ~" J* v$ S4 j* I
[color=#FFFFFF']
" a' z9 {! m7 G1 Q
& l% R$ C3 ~- P& `- _7 Z8 C
更详细的见dateman页--syntaxisabitarcane.只有root能设置时间。虽然每个用户可以有自己的时区,但时钟对每个人都是一样的。
, S8 ^7 b: ^- z* _4 V2 f3 O date只显示或设置软件时钟。clock命令同步硬件和软件时钟。用于系统启动时读取硬件时钟和设置软件时钟。如果两个时钟都需要设置,则先用date设置软件时钟,然后用clock-w设置硬件时钟。
% a( n9 m% u9 |9 Q
clock的-u告诉它硬件时钟是通用时间。必须正确使用-u选项。否则计算机将困惑到底是什么时间。
9 }5 E1 {. I9 Y8 P5 m 时钟必须小心改变。
Unix系统的许多部分要求时钟工作正常。例如,cron守侯
程序周期地运行命令。如果改变时钟,它可能迷惑它是否该运行命令。OnoneearlyUnixsystem,someonesettheclocktwentyyearsintothefuture,andcronwantedtorunalltheperiodiccommandsfortwentyyearsallatonce.现在版本的cron可以正确处理,但仍然要小心。大的前后跳跃比小的更危险。
" _( Q v, M z& {
当时钟错误时
( p% E, ?, w0 X- K/ I
Linux软件时钟不会始终精确。PC硬件产生的时间中断周期地运行软件时钟。如果系统运行了太多进程,服务于时间中断需要花费太多的时间,软件时钟启动靠后。硬件时钟独立运行并通常更精确。如果你的系统经常启动(比如不是
服务器的多数系统),那么通常时间很精确。
+ ~" c$ |7 |2 r2 e
如果需要调整硬件时钟,通常最简单的是重启动,进入BIOS设定屏幕,并在那里完成。这避免了改变系统时间可能导致的所有问题。如果不能通过BIOS,用date和clock设定新时间(以此顺序),但如果系统有部分工作不正常,必须准备重启动。
8 ]8 V! ]( Z$ N, E- K! q! U
连网的计算机(即使是通过modem)能通过与其他计算机时间比较来自动检查自己的时钟。如果知道保持很精确时间的其他计算机,那么2台计算机都将保持精确的时间。这可以使用rdate和netdate命令来完成。2个命令都检查远程的计算机(netdate可处理多台远程计算机),来同步本地计算机的时间。有规律地运行这样一个程序,你的计算机就可以保持与远程计算机一样精确的时间。
8 L0 p e& Q" u& r/ f+ s 测量孔(MeasuringHoles)
) s2 s( I/ \' V" D6 W& p; d 本附录包括用于测量文件系统中潜在的孔的程序的有趣的部分。Thesourcedistributionofthebookcontainsthefullsourcecode(sag/measure-holes/measure-holes.c).
& h0 Z- ~7 s8 q0 o7 z
intprocess(FILE*f,char*filename){
, p# r; _( Q6 ^6 c( ~1 L/ y; W9 Z staticchar*buf=NULL;
! m" n A( [# E& h. N# n' y9 \: { staticlongprev_block_size=-1;
# j5 o" A1 I/ E( v8 `
longzeroes;
" ], a, F0 }3 k! S" ~5 A9 f char*p;
5 Z; L3 y+ h2 l/ x5 e3 G, S if(buf==NULL││prev_block_size!=block_size){
3 |, H3 K) R- e+ |! d free(buf);
6 w l8 }( o5 k$ t
buf=xmalloc(block_size1);
/ m+ _2 q3 f* i6 T/ g* E, _
buf[block_size]=1;
7 G. V" O( t. P/ [) [
prev_block_size=block_size;
! O9 c% G' S0 L# K! {! S) Q }
- t, ^% N) V+ d B# {5 R5 R zeroes=0;
) p) Y( P' q" k* Y( W! v
while(fread(buf,block_size,1,f)==1){
+ Z$ e# X3 T) n5 R for(p=buf;*p==\\\'\\\\0\\\';)
$ D+ p/ B" k) L. {0 a p;
3 V' J' }7 z& w% T$ T if(p==bufblock_size)
6 Z* ^% C0 C$ `& _: G5 W zeroes=block_size;
9 P3 Y$ d4 R: J) [% q) R! X }
& `0 `) P. _$ f! t if(zeroes%26gt;0)
9 v& G. s* Q. z. ^5 a
printf("%ld%s\\\\n",zeroes,filename);
+ X7 b- J, m% T if(ferror(f)){
. G6 }7 x5 c$ l+ j8 o- s
errormsg(0,-1,"readfailedfor`%s\\\'",filename);
( N/ k0 L" U7 @8 Z
return-1;
0 j& N8 J @0 S# ]
}
, K. H x' W; q, [
return0;
9 w# N: e* Z4 B6 e' H4 m- t
}