Shell 获取并设置日期及延时,延时可以用来在程序执行过程中等待一段时间(比如1秒),或是每隔几秒钟(或是几个月)监督某项任务。与时间和日期打交道需要理解如何描述并处理这两者。这则攻略会告诉你怎样使用日期以及延时。
预备知识
日期能够以多种格式呈现。在系统内部,日期被存储成一个整数,其取值为自1970年1月1日0时0分0秒3起所流逝的秒数。这种计时方式称为纪元时或Unix时间。
Unix认为UTC 1970年1月1日0点是纪元时间。POSIX标准推出后,这个时间也被称为POSIX时间。
可以在命令行中设置系统日期。下面来看看对其进行读取和设置的方法。
实战演练
可以以不同的格式来读取、设置日期。
(1) 读取日期:
$ date
Thu May 20 23:09:04 IST 2010
(2) 打印纪元时:
$ date +%s
1290047248
data
命令可以将很多不同格式的日期转换成纪元时。这就允许你使用多种日期格式作为输入。如果要从系统日志中或者其他标准应用程序生成的输出中获取日期信息,就完全不用烦心日期的格式问题。
将日期转换成纪元时:
$ date --date "Wed mar 15 08:09:16 EDT 2017" +%s
1489579718
选项--date
指定了作为输入的日期。我们可以使用任意的日期格式化选项来打印输出。data
命令可以根据指定的日期找出这一天是星期几:
$ date --date "Jan 20 2001" +%A
Saturday
(3) 用带有前缀+
的格式化字符串作为date
命令的参数,可以按照你的选择打印出相应格式的日期。例如:
$ date "+%d %B %Y"
20 May 2010
(4) 设置日期和时间:
# date -s "格式化的日期字符串"
例如:
# date -s "21 June 2009 11:01:22"
如果系统已经联网,可以使用ntpdate
来设置日期和时间:
/usr/sbin/ntpdate -s time-b.nist.gov
(5) 要优化代码,首先得先进行测量。date
命令可以用于计算一组命令所花费的执行时间:
#!/bin/bash
#文件名: time_take.sh
start=(date +%s)
commands;
statements;
end=(date +%s)
difference=(( end - start))
echo Time taken to execute commands isdifference seconds.
date
命令的最小精度是秒。对命令计时的另一种更好的方式是使用time
命令:
time commandOrScriptName.
工作原理
Unix纪元时被定义为从世界标准时间(Coordinated Universal Time,UTC)4 1970年1月1日0时0分0秒起至当前时刻的总秒数,不包括闰秒5。当计算两个日期或两段时间的差值时,需要用到纪元时。将两个日期转换成纪元时并计算出两者之间的差值。下面的命令计算了两个日期之间相隔了多少秒:
UTC(Coordinated Universal Time),又称世界标准时间或世界协调时间。UTC是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。
5闰秒是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中(也可能是季末)对协调世界时增加或减少1秒的调整。
secs1=`date -d "Jan 2 1970"
secs2=`date -d "Jan 3 1970"
echo "There are `expr secs2 -secs1` seconds between Jan 2 and Jan 3"
There are 86400 seconds between Jan 2 and Jan 3
对用户而言,以秒为单位显示从1970年1月1日午夜截止到当前的秒数,实在是不太容易读懂。date
命令支持以用户易读的格式输出日期。
下表列出了date
命令所支持的格式选项。
日期内容 | 格式 |
---|---|
工作日(weekday) | %a (例如:Sat) %A (例如:Saturday) |
月 | %b (例如:Nov) %B (例如:November) |
日 | %d (例如:31) |
特定格式日期(mm/dd/yy) | %D (例如:10/18/10) |
年 | %y (例如:10) %Y (例如:2010) |
小时 | %I 或%H (例如:08) |
分钟 | %M (例如:33) |
秒 | %S (例如:10) |
纳秒 | %N (例如:695208515) |
Unix纪元时(以秒为单位) | %s (例如:1290049486) |
补充内容
编写以循环方式运行的监控脚本时,设置时间间隔是必不可少的。让我们来看看如何生成延时。
在脚本中生成延时
sleep
命令可以延迟脚本执行一段时间(以秒为单位)。下面的脚本使用tput
和sleep
从0开始计时到40秒:
#!/bin/bash
#文件名: sleep.sh
echo Count:
tput sc
# 循环40秒
for count in `seq 0 40`
do
tput rc
tput ed
echo -n $count
sleep 1
done
在上面的例子中,变量依次使用了由seq
命令生成的一系列数字。我们用tput sc
存储光标位置。在每次循环中,通过tput rc
恢复之前存储的光标位置,在终端中打印出新的count
值,然后使用tputs ed
清除从当前光标位置到行尾之间的所有内容。行被清空之后,脚本就可以显示出新的值。sleep
可以使脚本在每次循环迭代之间延迟1秒钟。