时间/日期和计时命令
date
只需调用,date 就会将日期和时间打印到标准输出(stdout)
。这个命令有趣的地方在于它的格式和解析选项。
样例 16-10. 使用 date 命令
复制 #!/bin/bash
# 练习'date'命令
echo "The number of days since the year's beginning is ` date +%j `."
# 需要一个前导的'+'来调用格式。
# %j给出了年初以来的天数。
echo "The number of seconds elapsed since 01/01/1970 is ` date +%s `."
# %s给出了自从"UNIX时期(UNIX epoch)"开始至今已过的秒数,
# 但是这有什么用呢?
prefix = temp
suffix = $( date +%s ) # “日期”的“+%s”选项是GNU特有的。
filename = $prefix . $suffix
echo "Temporary filename = $filename"
# 它非常适合创建 “唯一且随机” 的临时文件名,
# 甚至比使用$$还好.
# 你可以阅读'date' man手册,了解更多格式选项。
exit 0
-u
选项给出了UTC时间 (世界标准时间)。
复制 bash$ date
Fri Mar 29 21 :07:39 MST 2002
bash$ date -u
Sat Mar 30 04 :07:42 UTC 2002
此选项便于计算不同日期之间的时间。
样例 16-11. 日期 计算
复制 #!/bin/bash
# date-calc.sh
# 作者: Nathan Coulter
# 仅在本书中允许使用(谢谢)!
MPHR = 60 # 每小时的分钟数。
HPD = 24 # 每天的小时数。
diff () {
printf '%s' $(( $(date - u - d"$TARGET" +% s) -
$(date -u -d"$CURRENT" +%s)))
# %d = 当前月份中的第几天。
}
CURRENT = $( date -u -d '2007-09-01 17:30:24' '+%F %T.%N %Z')
TARGET = $( date -u -d '2007-12-25 12:30:00' '+%F %T.%N %Z')
# %F = 完整日期, %T = %H:%M:%S, %N = 纳秒, %Z = 时区。
printf '\nIn 2007, %s ' \
"$( date -d "$CURRENT +
$(( $(diff) / $MPHR / $MPHR / $HPD / 2 )) days" '+%d %B')"
# %B = name of month ^ halfway
printf 'was halfway between %s ' "$( date -d "$CURRENT" '+%d %B')"
printf 'and %s\n' "$( date -d "$TARGET" '+%d %B')"
printf '\nOn %s at %s, there were\n' \
$( date -u -d "$CURRENT" +%F ) $( date -u -d "$CURRENT" +%T )
DAYS = $(( $(diff) / $MPHR / $MPHR / $HPD ))
CURRENT = $( date -d "$CURRENT +$DAYS days" '+%F %T.%N %Z')
HOURS = $(( $(diff) / $MPHR / $MPHR ))
CURRENT = $( date -d "$CURRENT +$HOURS hours" '+%F %T.%N %Z')
MINUTES = $(( $(diff) / $MPHR ))
CURRENT = $( date -d "$CURRENT +$MINUTES minutes" '+%F %T.%N %Z')
printf '%s days, %s hours, ' "$DAYS" "$HOURS"
printf '%s minutes, and %s seconds ' "$MINUTES" "$( diff )"
printf 'until Christmas Dinner!\n\n'
# 练习:
# --------
# 重写diff()函数使其能够接受传参,
# 而不是使用全局变量。
date 命令有相当多的输出 选项。例如,%N
给出当前时间的纳秒部分。该命令的一个有趣的用途是可以生成随机整数。
复制 date +%N | sed -e 's/000$//' -e 's/^0//'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# 如果存在,去除前后的零。
# 生成的整数的长度取决于去除了多少个零。
# 115281032
# 63408725
# 394504284
还有远远不止这些选项(尝试执行man date )
复制 date +%j
# 输出今天在当年中的位置(自1月1日以来经过的天数)
date +%k%M
# 作为一个单独的数字字符串,以24小时制输出当前小时和分钟。
# 'TZ'参数允许覆盖默认时区。
date # Mon Mar 28 21:42:16 MST 2005
TZ = EST date # Mon Mar 28 23:42:16 EST 2005
# 感谢Frank Kannemann and Pete Sjoberg的点子.
SixDaysAgo = $( date --date= '6 days ago')
OneMonthAgo = $( date --date= '1 month ago') # 4周前(不是一个月!)
OneYearAgo = $( date --date= '1 year ago')
你也可以参见样例 3-4 和样例 A-43 。
zdump
时区转储: 打印指定时区的时间。
复制 bash$ zdump EST
EST Tue Sep 18 22 :09:22 2001 EST
time
输出执行命令的详细计时统计信息。
time ls -l /
会给出类似这样的信息:
复制 real 0 m0.067s
user 0 m0.004s
sys 0 m0.005s
另请参阅上一节中的非常相似的times 命令。
touch
这是一个用于将文件的访问/修改时间更新为当前系统时间或其他指定时间的实用程序,对于创建新文件也很有用。假设zzz
以前不存在,命令touch zzz
将创建一个零长度的新文件,名为zzz
。以这种方式对空文件进行时间标记对于存储日期信息很有用,例如在跟踪项目的修改时间方面。
在执行cp-u (复制/更新) 之前,使用touch 命令来更新那些你不希望覆盖的文件的时间戳(time stamp)。
例如,如果目录/home/bozo/tax_audit
包含文件spreadsheet-051606.data
、spreadsheet-051706.data
和spreadsheet-051806.data
,然后执行touch spreadsheet*.data 会保护这些文件在执行cp -u /home/bozo/financial_info/spreadsheet*data /home/bozo/tax_audit 时不会被相同文件名文件覆盖。
at
at 作业控制命令在指定时间执行一组给定的命令。从表面上看,它类似于cron ,但是,at 主要用于一次性执行命令集。
at 2pm January 15 提示在该时点执行一组命令。这些命令需要与shell脚本兼容,出于所有实际目的,用户一次输入一行可执行shell脚本。键入Ctl-D 终止。
使用-f
选项或输入重定向 (<),at 从文件中读取命令列表。这个文件是一个可执行的shell脚本,当然,它应该是非交互式的。在文件中包含run-parts 命令以执行一组不同的脚本是一个非常明智的选择。
复制 bash$ at 2 :30 am Friday < at-jobs.list
job 2 at 2000 -10-27 02 :30
batch
batch 作业控制命令类似于at 命令,但当系统负载降至低于.8时,它会运行一个命令列表。类似于at ,它可以使用-f
选项从文件里读取命令。
批处理 的概念可以追溯到大型计算机时代。这意味着在没有用户干预的情况下运行一组命令。
cal
将格式整齐的月历传递给标准输出(stdout)
。包含今年以及过去和未来几年。
sleep
该命令是等待循环 的shell等效项。它暂停指定的秒数,什么也不做。它可以用于定时或在后台运行的进程中,经常用于检查特定事件 (轮询)中,如样例 32-6 所示。
usleep
Microsleep (在希腊语中,这个u 可以读作mu ,或者是前缀micro )。该命令与上述sleep 相同,但是它是以微秒的间隔时间"sleeps"。它可以用于细粒度的计时,以及以非常频繁的间隔轮询运行中的进程。
该命令是红帽系统initscripts / rc-scripts 包中的一部分。
hwclock,clock
hwclock 命令访问或调整机器的硬件时钟(hardware clock)。有些选项需要root 权限。在启动时,/etc/rc.d/rc.sysinit
启动文件使用hwclock 命令从硬件时钟中设置系统时间。
clock 命令是hwclock 的同义词(synonym)。