时间及其同步、定时任务、时间戳
一、GMT、UTC、CST、DST 时间概念
1、通用协调时(UTC, Universal Time Coordinated)。
整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。
2、GMT
格林威治标准时间 (Greenwich Mean Time)指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。(UTC与GMT时间基本相同,本文中不做区分)
3、CST:中国标准时间 (China Standard Time)
GMT + 8 = UTC + 8 = CST
4、DST
夏令时(Daylight Saving Time) 指在夏天太阳升起的比较早时,将时钟拨快一小时,以提早日光的使用。(中国不使用)
二、使用chrony方式集群同步时间
在主节点配置:
1、下载:(每个节点都下) yum install chrony 2、配置: #vi /etc/chrony.conf #allow 10.0.0.0/8 local stratum 10 #允许本地同步 3、启动 #systemctl enable chronyd.service #systemctl start chronyd.service 4、验证 #chronyc sources
在从节点配置:
1、配置: #vi /etc/chrony.conf(删除其他iburst) #server node1 iburst 2、启动 #systemctl enable chronyd.service #systemctl start chronyd.service 3、验证 #chronyc sources
三、ntpd和ntpdate同步时间
1、ntpd和ntpdate区别
ntpd在实际同步时间时是一点点的校准过来时间的,最终把时间慢慢的校正对。(校准时间,渐变)
ntpdate不会考虑其他程序是否会阵痛,直接调整时间。(调整时间,跳变)
使用ntpd服务,要好于ntpdate加cron的组合。
因为,ntpdate同步时间,会造成时间的跳跃,对一些依赖时间的程序和服务会造成影响。比 如sleep,timer等。而且,ntpd服务可以在修正时间的同时,修正cpu tick。
理想的做法为,在开机的时候,使用ntpdate强制同步时间,在其他时候使用ntpd服务来同步时间。
ntpd服务运行后, 先是每64秒与上源服务器同步一次, 根据每次同步时测得的误差值经复杂计算逐步调整自己的时间, 随着误差减小, 逐步增加同步的间隔. 每次跳动, 都会重复这个调整的过程.
2、ntpd
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
3、ntpdate+cron同步时间
ntpdate同步阿里云时间报错 # ntpdate ntp2.aliyun.com 3 Aug 14:18:54 ntpdate[20724]: the NTP socket is in use, exiting 解决:停掉ntpd # service ntpd stop Redirecting to /bin/systemctl stop ntpd.service 同步成功 # ntpdate ntp2.aliyun.com 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
4、Linux本地时间
删除系统里的当地时间链接。
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)。
hwclock -w
执行命令date -R
查看时区信息是否生效
四、时区修改
1、timedatectl
#:/usr/share/zoneinfo/Asia# timedatectl Local time: 六 2020-06-13 10:18:57 CST Universal time: 六 2020-06-13 02:18:57 UTC RTC time: 六 2020-06-13 02:18:58 Time zone: Africa/Libreville (CST, +0800) Network time on: yes NTP synchronized: yes RTC in local TZ: no
2、列出时区
# timedatectl list-timezones
3、设置时区
timedatectl set-timezone Asia/Shanghai ##等价于 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 022501012009.40 月日十分年.秒 2009年 02月 25日 星期三 01:01:40 CST
补充:输出20天前是日期
date -d "20 days ago" "+%Y%m%d" 20240815
4、查看硬件时间用hwclock或者clock命令:
#hwclock 2019年07月22日 星期一 08时22分29秒 -0.490264 秒 #clock 2019年07月22日 星期一 08时23分00秒 -0.555040 秒
5、将硬件时间写入到系统时间:
#hwclock -s
6、将系统时间写入到硬件时间
#hwclock -w
7、显示今天是周几
$ date '+%w' 5
显示今天是今年的第几天
cal -j
8、contab定时
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/code.txt
在这里我添加了一个定时任务*/1 * * * * echo"hello world">>/data/code.txt :意思是每隔一分钟打印一次hello world,并且重定向到了/data/code.txt文件里面,几分钟过后查看code.txt,出现了如下内容,说明这个定时任务已经开始执行
******定时任务书写要领******
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_back.sh 2> /mnt/hdd2/pg_data_back/error.log &
(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 > file.log 2>&1 & 。
nohup放在命令的开头,表示不挂起(no hang up),也即,关闭终端或者退出某个账号,进程也继续保持运行状态,一般配合&符号一起使用,如:
nohup ./bin/frps -c frps.ini >/dev/null 2>&1 &
bash默认情况下,在exit时并不会向后台的进程发送SIGHUP信号!!!
shopt | grep huponexit huponexit off
这个命令的结果如果是off(默认值是off),也就是说,在exit bash时,并不会向后台的进程发送SIGHUP信号,所以退出后进程依然存在,用不用nohup没区别!
6:定时任务执行的脚本要规范路径 (例如 /server/script)
7:配置定时任务要规范操作过程
8:定时任务执行特殊的字符需要进行转义,否则会报错,例如 百分号% 转义 \%
9:定时任务脚本中如果涉及使用到环境变量,必须在脚本中重新定义,不然,定时任务识别不了
补充:crontab 支持的所有格式
1. 详细时间字段格式
crontab
时间计划中有五个字段,从左到右分别为:
* * * * * [command to execute]
- 分钟 (0 - 59)
- 小时 (0 - 23)
- 月份中的日期 (1 - 31)
- 月份 (1 - 12)
- 星期中的日 (0 - 7) (0 和 7 都代表星期日)
例如:30 2 * * 1 [command]
表示每星期一凌晨 2:30 执行一次指定命令。
2. 特殊字符串格式
- @reboot: 在每次系统重启后执行。
- @yearly 或 @annually: 每年执行一次,等同于
0 0 1 1 *
。 - @monthly: 每月执行一次,等同于
0 0 1 * *
。 - @weekly: 每周执行一次,等同于
0 0 * * 0
。 - @daily 或 @midnight: 每天执行一次,等同于
0 0 * * *
。 - @hourly: 每小时执行一次,等同于
0 * * * *
。
六、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格式输出日期和时间 例如:2006年8月7日,星期一 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 的日期和时间 (如:2005年3月3日 星期四 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 纳秒(000000000-999999999) %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"
» date +"%F %H:%M:%S" 2021-03-26 09:50:19
CentOS 7 设置系统时间为中国时区并启用NTP同步 - BillyLV - 博客园 (cnblogs.com)