2023年11月30日发(作者:)

时间及其同步、定时任务、时间戳

⼀、GMTUTCCSTDST 时间概念

1、通⽤协调时(UTC, Universal Time Coordinated)

整个地球分为⼆⼗四时区,每个时区都有⾃⼰的本地时间。在国际⽆线电通信场合,为了统⼀起见,使⽤⼀个统⼀的时间,称为通⽤协调时

(UTC, Universal Time Coordinated)

2GMT

格林威治标准时间 (Greenwich Mean Time)指位于英国伦敦郊区的皇家格林尼治天⽂台的标准时间,因为本初⼦午线被定义在通过那⾥的经

线。(UTCGMT时间基本相同,本⽂中不做区分)

3CST中国标准时间 (China Standard Time)

GMT + 8 = UTC + 8 = CST

4DST

夏令时(Daylight Saving Time) 指在夏天太阳升起的⽐较早时,将时钟拨快⼀⼩时,以提早⽇光的使⽤。(中国不使⽤)

⼆、使⽤chrony⽅式集群同步时间

在主节点配置:

1、下载:(每个节点都下)

yum install chrony

2、配置:

#vi /etc/

#allow 10.0.0.0/8

local stratum 10 #允许本地同步

3、启动

#systemctl enable e

#systemctl start e

4、验证

#chronyc sources

在从节点配置:

1、配置:

#vi /etc/(删除其他iburst)

#server node1 iburst

2、启动

#systemctl enable e

#systemctl start e

3、验证

#chronyc sources

三、ntpdntpdate同步时间

1ntpdntpdate区别

ntpd在实际同步时间时是⼀点点的校准过来时间的,最终把时间慢慢的校正对。(校准时间,渐变)

ntpdate不会考虑其他程序是否会阵痛,直接调整时间。(调整时间,跳变)

使⽤ntpd服务,要好于ntpdatecron的组合。

因为,ntpdate同步时间,会造成时间的跳跃,对⼀些依赖时间的程序和服务会造成影响。⽐ sleeptimer等。⽽且,ntpd服务可以在修正

时间的同时,修正cpu tick

理想的做法为,在开机的时候,使⽤ntpdate强制同步时间,在其他时候使⽤ntpd服务来同步时间。

要注意的是,ntpd 有⼀个⾃我保护设置: 如果本机与上源时间相差太⼤,ntpd 不运⾏。所以新设置的时间服务器⼀定要先 ntpdate 从上源取

得时间初值, 然后启动 ntpd服务。

ntpd服务运⾏后, 先是每64秒与上源服务器同步⼀次, 根据每次同步时测得的误差值经复杂计算逐步调整⾃⼰的时间, 随着误差减⼩, 逐步增加

同步的间隔. 每次跳动, 都会重复这个调整的过程.

2ntpd

ntpd⾃动会校准时间,ntpdate ip是⼿动同步

# ntpstat

synchronised to unspecified (185.209.85.222) at stratum 3

time correct to within 163 ms

polling server every 64 s

ntp服务,默认只会同步系统时间。如果想要让ntp同时同步硬件时间,可以设置/etc/sysconfig/ntpd ⽂件。

/etc/sysconfig/ntpd⽂件中,添加 SYNC_HWCLOCK=yes 这样,就可以让硬件时间与系统时间⼀起同步。

防⽕墙及严的

iptables -I INPUT -p udp -m udp --sport 123 -j ACCEPT

3ntpdate+cron同步时间

ntpdate同步阿⾥云时间报错

# ntpdate

3 Aug 14:18:54 ntpdate[20724]: the NTP socket is in use, exiting

解决:停掉ntpd

# service ntpd stop

Redirecting to /bin/systemctl stop e

同步成功

# ntpdate

9 Oct 13:21:31 ntpdate[20753]: step time server 203.107.6.88 offset 416098894.202070 sec

设置计划任务(每天12点整同步⼀次)

0 12 * * * * /usr/sbin/ntpdate 192.168.0.1

4Linux本地时间

删除系统⾥的当地时间链接。

sudo rm /etc/localtime

vim打开并编辑配置⽂件/etc/sysconfig/clock

sudo vi /etc/sysconfig/clock

添加Zone=Asia/Shanghai

查询亚洲时区列表

ls /usr/share/zoneinfo/Asia/

执⾏命令更新时区修改内容。

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

更新硬件时钟(RTC)。

##等价于

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

查看时区

date -R

5、设置⽇期时间:timedatectl set-time “YYYY-MM-DD HH:MM:SS”

设置硬件时钟为本地时间:timedatectl set-local-rtc 1

五、系统时间和硬件时间

系统时间: ⼀般说来就是我们执⾏ date命令看到的时间,linux系统下所有的时间调⽤(除了直接访问硬件时间的命令)都是使⽤的这个时

间。

硬件时间:主板上BIOS中的时间,由主板电池供电来维持运⾏,系统开机时要读取这个时间,并根据它来设定系统时间(注意:系统启动时

根据硬件时间设定系统时间的过程可能存在时区换算,这要视具体的系统及相关设置⽽定)。

1、查看当前系统时间date

# date

2019 07 22 星期⼀ 08:12:38 CST

2、设置系统时间date -s +时间

# date -s 08:21:22

2019 07 22 星期⼀ 08:21:22 CST

3、设置系统时间时,如果还需要设置⽇期,则要将⽇期与时间值⽤双引号包裹起来

# date -s "2019/7/22 8:15:00" “年⽉⽇:::

2019 07 22 星期⼀ 08:15:00 CST

# date .40 ⽉⽇⼗分年.

2009 02 25 星期三 01:01:40 CST

4、查看硬件时间⽤hwclock或者clock命令:

#hwclock

20190722 星期⼀ 082229 -0.490264

#clock

20190722 星期⼀ 082300 -0.555040

5、将硬件时间写⼊到系统时间:

#hwclock -s

6、将系统时间写⼊到硬件时间

#hwclock -w

7、显⽰今天是周⼏

$ date '+%w'

5

显⽰今天是今年的第⼏天

cal -j

8contab定时

vi /etc/crontab命令可以看到定时任务的书写格式

# vi /etc/crontab

SHELL=/bin/bash #SHELL变量指定了系统要使⽤哪个shell

PATH=/sbin:/bin:/usr/sbin:/usr/bin #PATH变量指定了系统执⾏命令的路径

MAILTO=root #MAILTO变量指定了crond的任务执⾏信息将通过电⼦邮件发送给root⽤户,如果MAILTO 量的值为空,则表⽰不发送任务执⾏信息给⽤户

# For details see man 4 crontabs man帮助第四部分

# Example of job definition:

# .---------------- minute (0 - 59) #分钟

# | .------------- hour (0 - 23) #⼩时

# | | .---------- day of month (1 - 31) #⽇期

# | | | .------- month (1 - 12) OR jan,feb,mar,apr ... #⽉份

# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri, sat #

# | | | | |

# * * * * * user-name command to be executed

在以上各个字段中,还可以使⽤以下特殊字符:

星号(*):代表每的意思,例如month字段如果是星号,则表⽰每⽉都执⾏该命令操作。

逗号(,):可以⽤逗号隔开的值指定⼀个列表范围,例如,“1,2,5,7,8,9”

横杠(-):可以⽤整数之间的横杠表⽰⼀个整数范围,例如“2-6”表⽰“2,3,4,5,6”

斜线(/):可以⽤斜线指定时间的间隔频率,例如“0-23/2”表⽰每两⼩时执⾏⼀次。同时斜线可以和星号⼀起使⽤,例如*/10,如果⽤在minute字段,

表⽰每⼗分钟执⾏⼀次。

crontab -l :列出当前⽤户的crontab⽂件内容

* * * * */usr/local/gse/agent/bin/gsectl watch

crontab -e :编辑当前⽤户的crontab⽂件内容

#crontab -e

*/1 * * * * echo"beautiful days">>/data/

在这⾥我添加了⼀个定时任务*/1 * * * * echo"hello world">>/data/ :意思是每隔⼀分钟打印⼀次hello world,并且重定向到了/data/

件⾥⾯,⼏分钟过后查看,出现了如下内容,说明这个定时任务已经开始执⾏

******定时任务书写要领******

1:定时任务要加注释

2:定时任务命令或脚本结尾加 &>/dev/null >/dev/null 2>&1 1>/dev/null 2>/dev/null

3:定时任务执⾏shell脚本前加/bin/sh,定时任务执⾏shell脚本不必添加执⾏权限

4:定时任务命令或程序尽量写到脚本⾥,定时任务只要执⾏脚本即可

5:⽣产任务程序不要随意打印输出信息

59 23 * * * /bin/bash /mnt/pg_data_back/pg_data_ 2> /mnt/hdd2/pg_data_back/ &

2> :将错误输出到哪⾥,)

0 表⽰stdin,标准输⼊

1 表⽰stdout,标准输出

2 表⽰stderr,标准错误

> file 表⽰将标准输出输出到file中,也就相当于 1>file

2> error 表⽰将错误输出到error⽂件中

2>&1 也就表⽰将错误重定向到标准输出上

2>&1 >file :错误输出到终端,标准输出重定向到⽂件file,等于 > file 2>&1(标准输出重定向到⽂件,错误重定向到标准输出)

& 放在命令到结尾,表⽰后台运⾏,防⽌终端⼀直被某个进程占⽤,这样终端可以执⾏别到任务,配合 >file 2>&1可以将log保存到某个⽂件

中,但如果终端关闭,则进程也停⽌运⾏。如 command > 2>&1 &

nohup放在命令的开头,表⽰不挂起(no hang up),也即,关闭终端或者退出某个账号,进程也继续保持运⾏状态,⼀般配合&符号⼀起

使⽤,如:

nohup ./bin/frps -c >/dev/null 2>&1 &

bash默认情况下,在exit时并不会向后台的进程发送SIGHUP信号

shopt | grep huponexit

huponexit off

这个命令的结果如果是off(默认值是off),也就是说,在exit bash时,并不会向后台的进程发送SIGHUP信号,所以退出后进程依然存在,

⽤不⽤nohup没区别!

6:定时任务执⾏的脚本要规范路径 (例如 /server/script)

7:配置定时任务要规范操作过程

8:定时任务执⾏特殊的字符需要进⾏转义,否则会报错,例如 百分号% 转义 %

9:定时任务脚本中如果涉及使⽤到环境变量,必须在脚本中重新定义,不然,定时任务识别不了

六、shell中的时间表达

1、参数

[root@root ~]#date --help

⽤法:date [选项]... [+格式]

或:date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]

Display the current time in the given FORMAT, or set the system date.

Mandatory arguments to long options are mandatory for short options too.

-d, --date=STRING display time described by STRING, not 'now'

-f, --file=DATEFILE like --date once for each line of DATEFILE

-I[TIMESPEC], --iso-8601[=TIMESPEC] output date/time in ISO 8601 format.

TIMESPEC='date' for date only (the default),

'hours', 'minutes', 'seconds', or 'ns' for date

and time to the indicated precision.

-r, --reference=⽂件 显⽰⽂件指定⽂件的最后修改时间

-R, --rfc-2822 RFC 2822格式输出⽇期和时间

例如:200687⽇,星期⼀ 12:34:56 -0600

--rfc-3339=TIMESPEC output date and time in RFC 3339 format.

TIMESPEC='date', 'seconds', or 'ns' for

date and time to the indicated precision.

Date and time components are separated by

a single space: 2006-08-07 12:34:56-06:00

-s, --set=STRING set time described by STRING

-u, --utc, --universal print or set Coordinated Universal Time (UTC)

--help 显⽰此帮助信息并退出

--version 显⽰版本信息并退出

给定的格式FORMAT 控制着输出,解释序列如下:

%% ⼀个⽂字的 %

%a 当前locale 的星期名缩写(例如: ⽇,代表星期⽇)

%A 当前locale 的星期名全称 (如:星期⽇)

%b 当前locale 的⽉名缩写 (如:⼀,代表⼀⽉)

%B 当前locale 的⽉名全称 (如:⼀⽉)

%c 当前locale 的⽇期和时间 (如:200533 星期四 23:05:25)

%C 世纪;⽐如 %Y,通常为省略当前年份的后两位数字(例如:20)

%d 按⽉计的⽇期(例如:01)

%D 按⽉计的⽇期;等于%m/%d/%y

%e 按⽉计的⽇期,添加空格,等于%_d

%F 完整⽇期格式,等价于 %Y-%m-%d

%g ISO-8601 格式年份的最后两位 (参见%G)

%G ISO-8601 格式年份 (参见%V),⼀般只和 %V 结合使⽤

%h 等于%b

%H ⼩时(00-23)

%I ⼩时(00-12)

%j 按年计的⽇期(001-366)

%k hour, space padded ( 0..23); same as %_H

%l hour, space padded ( 1..12); same as %_I

%m month (01..12)

%M minute (00..59)

%n 换⾏

%N 纳秒(000009)

%p 当前locale 下的"上午"或者"下午",未知时输出为空

%P %p 类似,但是输出⼩写字母

%r 当前locale 下的 12 ⼩时时钟时间 (如:11:11:04 下午)

%R 24 ⼩时时间的时和分,等价于 %H:%M

%s UTC 时间 1970-01-01 00:00:00 以来所经过的秒数

%S (00-60)

%t 输出制表符 Tab

%T 时间,等于%H:%M:%S

%u 星期,1 代表星期⼀

%U ⼀年中的第⼏周,以周⽇为每星期第⼀天(00-53)

%V ISO-8601 格式规范下的⼀年中第⼏周,以周⼀为每星期第⼀天(01-53)

%w ⼀星期中的第⼏⽇(0-6)0 代表周⼀

%W ⼀年中的第⼏周,以周⼀为每星期第⼀天(00-53)

%x 当前locale 下的⽇期描述 (如:12/31/99)

%X 当前locale 下的时间描述 (如:23:13:48)

%y 年份最后两位数位 (00-99)

%Y 年份

%z +hhmm 数字时区(例如,-0400)

%:z +hh:mm 数字时区(例如,-04:00)

%::z +hh:mm:ss 数字时区(例如,-04:00:00)

%:::z 数字时区带有必要的精度 (例如,-04+05:30)

%Z 按字母表排序的时区缩写 (例如,EDT)

默认情况下,⽇期的数字区域以0 填充。

The following optional flags may follow '%':

- (hyphen) do not pad the field

_ (underscore) pad with spaces

0 (zero) pad with zeros

^ use upper case if possible

# use opposite case if possible

在任何标记之后还允许⼀个可选的域宽度指定,它是⼀个⼗进制数字。

作为⼀个可选的修饰声明,它可以是E,在可能的情况下使⽤本地环境关联的

表⽰⽅式;或者是O,在可能的情况下使⽤本地环境关联的数字符号。

Examples:

Convert seconds since the epoch (1970-01-01 UTC) to a date

$ date --date='@2147483647'

Show the time on the west coast of the US (use tzselect(1) to find TZ)

$ TZ='America/Los_Angeles' date

Show the local time for 9AM next Friday on the west coast of the US

$ date --date='TZ="America/Los_Angeles" 09:00 next Fri'

2、时间戳转换

date -d "2021-03-04 17:09:20" +%s

1614848960

date --date='@1614848960'

2021 03 04 星期四 17:09:20 CST

date -d@1234567890 +"%Y-%m-%d %H:%M:%S"

2009-02-14 07:31:30

3、显⽰年⽉⽇时分秒:date +"%F %H:%M:%S"